【问题标题】:C++ How to sum only even values stored in vector?C ++如何仅对存储在向量中的偶数求和?
【发布时间】:2020-10-08 14:36:01
【问题描述】:

我是 C++ 新手,我完全不了解如何仅对 C++ 中存储在向量中的偶数值求和。

任务本身要求用户输入一定数量的随机整数,当输入为 0 时停止,然后返回偶数的数量和这些偶数的总和。

据我所知:

#include <algorithm>
#include <functional>
#include <iostream>
#include <vector>
#include <numeric>

using namespace std;

int main()

{
    vector<int> vet;
    int s = 1;
        while (s != 0) {
        std::cin >> s;
        vet.push_back(s);
    }


    int n = count_if(vet.begin(), vet.end(),
        [](int n) { return (n % 2) == 0; });
    cout << n << endl;
    

    //here is the start of my problems and lack of undertanding. Basically bad improv from previous method
    int m = accumulate(vet.begin(), vet.end(), 0,
        [](int m) { for (auto m : vet) {
              return (m % 2) == 0; });
              cout << m << endl;          //would love to see the sum of even values here

        
        
   return 0;
}

【问题讨论】:

  • 最后一个要累积的参数没有按照您的预期进行。请在问题中包含编译器错误消息
  • 您应该阅读std::accumulateop 参数的作用。

标签: c++ vector sum cycle


【解决方案1】:

要传递给std::accumulate的函数有2个值:当前累加值和当前元素值。

如果是偶数,你应该做的是添加值,如果不是,则不要更改。

int m = accumulate(vet.begin(), vet.end(), 0,
        [](int cur, int m) {
            if ((m % 2) == 0) {
                return cur + m; // add this element
            } else {
                return cur; // make no change
            }
        });

【讨论】:

    【解决方案2】:

    从 c++20 中,您可以分离出检查偶数的逻辑,以及对这些值求和的逻辑:

    auto is_even = [](int i) { return i % 2 == 0; };
    
    auto evens = vet | std::views::filter(is_even);
    
    auto sum = std::accumulate(std::begin(evens), std::end(evens), 0);  
    

    这是demo

    【讨论】:

    • vet | std::views::filter(is_even); 是否创建一个新向量?
    • @AyxanHaqverdili 不,这是范围的主要优点之一 :) evensview,它基本上是 vet 的迭代器。但是可以像容器一样使用它。
    • 我想知道为什么没有约束std::ranges::accumulate(范围抽象)? (view 类型受限于 range 概念,begin/end 上的大多数 std:: 算法可以通过它们的 std::range:: 算法直接应用于视图)。
    • ...我猜数字算法的必要概念并没有及时出现在 C++20 (p1813r0) 中。
    • @dfri 是的,甚至还有question 询问原因:)
    【解决方案3】:

    这是我的解决方案(如果不对,请在手机上写)

    你不需要一个向量形式,你只需要从输入中检查数字是否可以被 2 整除 我的解决方案:(有点丑)

    #include <iostream>
    
    using namespace std;
    
        int main()
        {
            int s {1};
            int sum{};
            int countNum{};
            while (s != 0)
            {
                cin >> s;
                if (s % 2 == 0)
                {
                    sum += s;
                    countNum++;
                }
            }
            cout << countNum << ' ' << sum;
        }
    

    【讨论】:

      【解决方案4】:

      我真的不知道你想在代码的第二部分做什么,但你可以通过这种方式对偶数求和,我想告诉你另一件事,当你使用命名空间 std 时,你不需要写std::cin只能直接写cin

      #include <iostream>
      #include <vector>
      
      using namespace std;
      
      int main()
      
      {
          vector<int> vet;
          int s = 1;
          //Take Input
          while (s != 0) {
              cin >> s;
              vet.push_back(s);
          }
          //count elements
          int elements_count = vet.size(); //vet.size() return the total number of elements of vector
      
          //store the sum here
          int sum=0;
      
          //loop on the vector and sum only even numbers
          for(int i=0;i<elements_count;i++){
              if(vet[i] %2 ==0)
                  sum += vet[i];//check of the element of index i in the vector is even if it true it will add to sum
          }
          cout << sum;
      
         return 0;
      }
      

      【讨论】:

      【解决方案5】:
      int sumEven=0;
      int v[100];
      int n;//number of elements you want to enter in the array
      do{cout<<"Enter n";
        cin>>n;}while(n<=0);
      //in a normal 1 dimensional array
      for(int i=0;i<n;i++)
      if(v[i]%2==0)
          sumEven+=v[i];
      
      //in a vector
      vector<int> v;
      for(vector<int>::iterator it=v.begin();it!=v.end();it++)
      if(*it%2==0)
          sumEven+=v[i];
      

      【讨论】:

        【解决方案6】:

        与上面的答案类似,但如果您还想保留偶数向量,这里有两种方法。

        #include <algorithm>
        #include <iostream>
        #include <numeric>
        #include <vector>
        
        int main() {
        
            std::vector<int> vec = {1,2,3,4,5,6,7,8,9,10};
        
            // Hold onto what we know is the right answer.
            int known_sum = 2+4+6+8+10;
        
            // Copy only even values into another vector
            std::vector<int> even_values;
            std::copy_if(vec.begin(), vec.end(),
                        std::back_inserter(even_values),
                        [](int val){ return val%2==0; });
        
            // Compute sum from even values vector
            int even_value_sum = std::accumulate(even_values.begin(), even_values.end(), 0);
        
            // Compute sum from original vector
            int even_value_second = std::accumulate(vec.begin(), vec.end(), 0, 
                [](int current_sum, int new_value) {
                    return new_value%2==0 ? current_sum + new_value:current_sum;
                }
            );
        
            // These should all be the same.
            std::cout << "Sum from only even vector: " << even_value_sum << std::endl;
            std::cout << "Sum from binary op in std accumulate: " << even_value_second << std::endl;
            std::cout << "Known Sum: " << known_sum << std::endl;
        
        }
        

        【讨论】:

          【解决方案7】:

          基于范围的 for 循环

          可以说,基于范围的 for 循环始终是 STL 算法的有效替代方案,尤其是在算法的运算符不重要的情况下。

          在 C++14 和 C++17 中

          例如在立即执行的可变 lambda 中包装基于范围的仅偶数累加 for 循环:

          #include <iostream>
          #include <vector>
          
          int main() {
              // C++17: omit <int> and rely on CTAD.
              const std::vector<int> v{1, 10, 2, 7, 4, 5, 8, 13, 18, 19};
              const auto sum_of_even_values = [sum = 0, &v]() mutable {
                  for (auto val : v) { 
                      if (val % 2 == 0) { sum += val; }
                  }
                  return sum;
              }();
              
              std::cout << sum_of_even_values; // 42
          }
          

          在 C++20 中

          从 C++20 开始,您可以在基于范围的 for 循环中使用初始化语句,以及 the ranges library,允许您在基于范围的 for 循环的初始化语句中声明二进制比较器,并且随后将其应用到循环的范围表达式以及std::ranges::filter_view 适配器:

          #include <iostream>
          #include <vector>
          #include <ranges>
          
          int main() {
              const std::vector v{1, 10, 2, 7, 4, 5, 8, 13, 18, 19};
          
              const auto sum_of_even_values = [sum = 0, &v]() mutable {
                  for (auto is_even = [](int i) { return i % 2 == 0; };
                       auto val : v | std::ranges::views::filter(is_even)) { 
                      sum += val;
                  }
                  return sum;
              }();
              
              std::cout << sum_of_even_values; // 42
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-02-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-12-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多