代码之家  ›  专栏  ›  技术社区  ›  Prasoon Saurav

如何总结C++向量的元素?

  •  194
  • Prasoon Saurav  · 技术社区  · 14 年前

    什么是 好的 求a中所有元素的和的方法 std::vector ?

    假设我有一个向量 std::vector<int> vector 其中包含一些元素。现在我想找出所有元素的和。相同的方法有哪些不同?

    10 回复  |  直到 6 年前
        1
  •  362
  •   Prasoon Saurav    8 年前

    实际上有很多方法。

    int sum_of_elems = 0;
    

    C++ 03

    1. 经典循环:

      for(std::vector<int>::iterator it = vector.begin(); it != vector.end(); ++it)
          sum_of_elems += *it;
      
    2. 使用标准算法:

      #include <numeric>
      
      sum_of_elems = std::accumulate(vector.begin(), vector.end(), 0);
      

      旗帜

      小心积累。 最后一个参数的类型不仅用于初始值,还用于结果的类型。如果在这里放置一个int,它将累积int,即使向量有浮点。如果要求和浮点数,请更改 0 0.0 0.0f (多亏了尼昂尼奥)。

    C++ 11与更高

    1. 使用 std::for_each :

      std::for_each(vector.begin(), vector.end(), [&] (int n) {
          sum_of_elems += n;
      });
      
    2. 使用基于范围的for循环(感谢Roger Pate):

      for (auto& n : vector)
          sum_of_elems += n;
      
        2
  •  30
  •   paxdiablo    7 年前

    Prason已经提供了许多不同的(和好的)方法来实现这一点,这些方法都不需要在这里重复。不过,我想建议另一种速度方法。

    如果你要做的比较多,你可能会考虑对你的向量进行“子分类”,这样一个元素的总和就可以单独维护(而不是 事实上 子类向量,由于缺少虚拟析构函数而不确定——我说的更多是一个包含和和和和向量的类, has-a 而不是 is-a ,并提供类似向量的方法)。

    对于空向量,总和设置为零。在每次插入向量时,将要插入的元素添加到和中。每次删除都要减去它。基本上, 任何东西 这样就可以改变底层向量被截取,以确保总和保持一致。

    这样,您就有了一个非常有效的O(1)方法来“计算”任何时间点的总和(只需返回当前计算的总和)。在调整总数时,插入和删除将花费稍长的时间,您应该考虑这个性能影响。

    由于计算总和的成本分摊到所有访问中,所以需要总和的向量比改变向量的频率更高,因此这些向量可能会从该方案中受益。显然,如果你每小时只需要求和,而向量每秒变化三千次,那么它就不合适了。

    这样就足够了:

    class UberVector:
        private Vector<int> vec;
        private int sum;
    
        public UberVector():
            vec = new Vector<int>();
            sum = 0;
    
        public getSum():
            return sum;
    
        public add (int val):
            rc = vec.add (val)
            if rc == OK:
                sum = sum + val
            return rc
    
        public delindex (int idx):
            val = 0
            if idx >= 0 and idx < vec.size:
                val = vec[idx]
            rc =  vec.delindex (idx)
            if rc == OK:
                sum = sum - val
            return rc
    

    显然,这是伪代码,您可能希望有更多的功能,但它显示了基本概念。

        3
  •  22
  •   James McNellis    10 年前

    当你能做的时候为什么要向前求和呢? 向后的 ?鉴于:

    std::vector<int> v;     // vector to be summed
    int sum_of_elements(0); // result of the summation
    

    我们可以使用订阅,倒数:

    for (int i(v.size()); i > 0; --i)
        sum_of_elements += v[i-1];
    

    我们可以使用范围检查“订阅”,倒数(以防万一):

    for (int i(v.size()); i > 0; --i)
        sum_of_elements += v.at(i-1);
    

    我们可以在for循环中使用反向迭代器:

    for(std::vector<int>::const_reverse_iterator i(v.rbegin()); i != v.rend(); ++i)
        sum_of_elements += *i;
    

    我们可以在for循环中使用前向迭代器,向后迭代(噢,很棘手!):

    for(std::vector<int>::const_iterator i(v.end()); i != v.begin(); --i)
        sum_of_elements += *(i - 1);
    

    我们可以使用 accumulate 使用反向迭代器:

    sum_of_elems = std::accumulate(v.rbegin(), v.rend(), 0);
    

    我们可以使用 for_each 对于使用反向迭代器的lambda表达式:

    std::for_each(v.rbegin(), v.rend(), [&](int n) { sum_of_elements += n; });
    

    所以,正如你所看到的,有很多方法可以把向量向后求和,就像把向量向前求和一样,其中一些方法更令人兴奋,并且提供了更大的出错机会。

        4
  •  14
  •   rafak    14 年前
    #include<boost/range/numeric.hpp>
    int sum = boost::accumulate(vector, 0);
    
        5
  •  10
  •   matiu    6 年前

    最简单的方法是使用 std:accumuate A的 vector<int> A :

    #include <numeric>
    cout << accumulate(A.begin(), A.end(), 0);
    
        6
  •  5
  •   Roger Pate    14 年前

    C++0X仅:

    vector<int> v; // and fill with data
    int sum {}; // or = 0 ... :)
    for (int n : v) sum += n;
    

    这类似于其他地方提到的boost-for each,在更复杂的情况下,与使用accumulate或for-each的有状态函数相比,它具有相同的清晰性优势。

        7
  •  5
  •   kriss    14 年前

    我是一个Perl用户,一个游戏,我们要找到每种不同的方法来增加一个变量…在这里没什么不同。如何找到C++中向量元素之和的答案可能是 an infinity

    我的2分钱:

    使用boost-foreach,摆脱难看的迭代器语法:

    sum = 0;
    BOOST_FOREACH(int & x, myvector){
      sum += x;
    }
    

    迭代索引(非常容易读取)。

    int i, sum = 0;
    for (i=0; i<myvector.size(); i++){
      sum += myvector[i];
    }
    

    另一个是破坏性的,像堆栈一样访问向量:

    while (!myvector.empty()){
       sum+=myvector.back();
       myvector.pop_back();
    }
    
        8
  •  2
  •   NeutronStar    7 年前

    还可以使用std::valarray,如下所示

    #include<iostream>
    #include<vector>
    #include<valarray>
    
    int main()
    {
    std::vector<int> seq{1,2,3,4,5,6,7,8,9,10};
    std::valarray<int> seq_add {seq.data(), seq.size()};
    std::cout << "sum = " << seq_add.sum() << "\n";
    
    return 0;
    }
    

    有些人可能会发现这种方法效率不高,因为valarray的大小需要和向量的大小一样大,初始化valarray也需要一些时间。

    在这种情况下,不要使用它,把它当作总结序列的另一种方法。

    谢谢

        9
  •  0
  •   Ravi Kumar Yadav    6 年前

    我找到了最简单的方法来求 矢量

    #include <iostream>
    #include<vector>
    using namespace std;
    
    int main()
    {
        vector<int>v(10,1);
        int sum=0;
        for(int i=0;i<v.size();i++)
        {
            sum+=v[i];
        }
        cout<<sum<<endl;
    
    }
    

    在这个程序中,我有一个大小为10的向量,由1初始化。我用数组中的简单循环计算了和。

        10
  •  -2
  •   Nick SamSmith1986    6 年前

    这很容易。C++ 11提供了一种总结向量元素的简单方法。

    sum = 0; 
    vector<int> vec = {1,2,3,4,5,....}
    for(auto i:vec) 
       sum+=i;
    cout<<" The sum is :: "<<sum<<endl;