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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3221812/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 12:22:20  来源:igfitidea点击:

How to sum up elements of a C++ vector?

c++stlvector

提问by Prasoon Saurav

What are the goodways of finding the sum of all the elements in a std::vector?

找到 a 中所有元素总和的方法是std::vector什么?

Suppose I have a vector std::vector<int> vectorwith a few elements in it. Now I want to find the sum of all the elements. What are the different ways for the same?

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

回答by Prasoon Saurav

Actually there are quite a few methods.

其实方法很多。

int sum_of_elems = 0;

C++03

C++03

  1. Classic for loop:

    for(std::vector<int>::iterator it = vector.begin(); it != vector.end(); ++it)
        sum_of_elems += *it;
    
  2. Using a standard algorithm:

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

    Important Note:The last argument's type is used not just for the initial value, but for the type of the resultas well. If you put an int there, it will accumulate ints even if the vector has float. If you are summing floating-point numbers, change 0to 0.0or 0.0f(thanks to nneonneo). See also the C++11 solution below.

  1. 经典 for 循环:

    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,即使向量有浮点数,它也会累积整数。如果要对浮点数求和,请更改00.00.0f(感谢 nneonneo)。另请参阅下面的 C++11 解决方案。

C++11 and higher

C++11 及更高版本

  1. b. Automatically keeping track of the vector type even in case of future changes:

    #include <numeric>
    
    sum_of_elems = std::accumulate(vector.begin(), vector.end(),
                                   decltype(vector)::value_type(0));
    
  2. Using std::for_each:

    std::for_each(vector.begin(), vector.end(), [&] (int n) {
        sum_of_elems += n;
    });
    
  3. Using a range-based for loop (thanks to Roger Pate):

    for (auto& n : vector)
        sum_of_elems += n;
    
  1. 湾 即使在未来发生变化的情况下,也能自动跟踪向量类型:

    #include <numeric>
    
    sum_of_elems = std::accumulate(vector.begin(), vector.end(),
                                   decltype(vector)::value_type(0));
    
  2. 使用std::for_each

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

    for (auto& n : vector)
        sum_of_elems += n;
    

回答by beahacker

The easiest way is to use std:accumuateof a vector<int> A:

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

#include <numeric>
cout << accumulate(A.begin(), A.end(), 0);

回答by paxdiablo

Prasoon has already offered up a host of different (and good) ways to do this, none of which need repeating here. I'd like to suggest an alternative approach for speed however.

Prasoon 已经提供了许多不同的(和好的)方法来做到这一点,这里不需要重复。但是,我想建议另一种速度方法。

If you're going to be doing this quite a bit, you may want to consider "sub-classing" your vector so that a sum of elements is maintained separately (not actuallysub-classing vector which is iffy due to the lack of a virtual destructor - I'm talking more of a class that contains the sum and a vector within it, has-arather than is-a, and provides the vector-like methods).

如果您打算这样做很多,您可能需要考虑“子分类”您的向量,以便单独维护元素的总和(实际上不是子分类向量,由于缺乏虚拟析构函数——我说的更多的是一个包含总和和向量的类,has-a而不是is-a,并提供类似向量的方法)。

For an empty vector, the sum is set to zero. On every insertion to the vector, add the element being inserted to the sum. On every deletion, subtract it. Basically, anythingthat can change the underlying vector is intercepted to ensure the sum is kept consistent.

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

That way, you have a very efficient O(1) method for "calculating" the sum at any point in time (just return the sum currently calculated). Insertion and deletion will take slightly longer as you adjust the total and you should take this performance hit into consideration.

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

Vectors where the sum is needed more often than the vector is changed are the ones likely to benefit from this scheme, since the cost of calculating the sum is amortised over all accesses. Obviously, if you only need the sum every hour and the vector is changing three thousand times a second, it won't be suitable.

需要求和的次数多于更改向量的向量可能会从该方案中受益,因为计算总和的成本会在所有访问中分摊。显然,如果你只需要每小时求和,而向量每秒变化三千次,那就不合适了。

Something like this would suffice:

像这样的东西就足够了:

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

Obviously, that's pseudo-code and you may want to have a little more functionality, but it shows the basic concept.

显然,这是伪代码,您可能想要更多功能,但它显示了基本概念。

回答by James McNellis

Why perform the summation forwards when you can do it backwards? Given:

当您可以向后进行求和时,为什么要向前进行求和?鉴于:

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

We can use subscripting, counting backwards:

我们可以使用下标,向后计数:

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

We can use range-checked "subscripting," counting backwards (just in case):

我们可以使用范围检查的“下标”,向后计数(以防万一):

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

We can use reverse iterators in a for loop:

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

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

We can use forward iterators, iterating backwards, in a for loop (oooh, tricky!):

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

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

We can use accumulatewith reverse iterators:

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

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

We can use for_eachwith a lambda expression using reverse iterators:

我们可以使用for_each反向迭代器与 lambda 表达式一起使用:

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

So, as you can see, there are just as many ways to sum the vector backwards as there are to sum the vector forwards, and some of these are much more exciting and offer far greater opportunity for off-by-one errors.

因此,如您所见,向后求和向量的方法与对向量向前求和的方法一样多,其中一些方法更令人兴奋,并为出现一对一错误提供了更大的机会。

回答by rafak

#include<boost/range/numeric.hpp>
int sum = boost::accumulate(vector, 0);

回答by NeutronStar

One can also use std::valarray<T>like this

也可以std::valarray<T>这样使用

#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;
}

Some may not find this way efficient since the size of valarrayneeds to be as big as the size of the vectorand initializing valarraywill also take time.

有些人可能认为这种方式效率不高,因为 的大小valarray需要与向量的大小一样大,并且初始化valarray也需要时间。

In that case, don't use it and take it as yet another way of summing up the sequence.

在这种情况下,不要使用它,而是将它作为总结序列的另一种方式。

回答by NeutronStar

C++0x only:

仅 C++0x:

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

This is similar to the BOOST_FOREACH mentioned elsewhere and has the same benefit of clarity in more complex situations, compared to stateful functors used with accumulate or for_each.

这与其他地方提到的 BOOST_FOREACH 类似,并且在更复杂的情况下具有相同的清晰度优势,与使用累加或 for_each 的有状态函子相比。

回答by kriss

I'm a Perl user, an a game we have is to find every different ways to increment a variable... that's not really different here. The answer to how many ways to find the sum of the elements of a vector in C++ is probably an infinity...

我是一个 Perl 用户,我们有一个游戏是找到各种不同的方法来增加一个变量......这里并没有真正的不同。在 C++ 中找到向量元素之和的方法有多少种答案可能是an infinity......

My 2 cents:

我的 2 美分:

Using BOOST_FOREACH, to get free of the ugly iterator syntax:

使用 BOOST_FOREACH,摆脱丑陋的迭代器语法:

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

iterating on indices (really easy to read).

迭代索引(真的很容易阅读)。

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

This other one is destructive, accessing vector like a stack:

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

while (!myvector.empty()){
   sum+=myvector.back();
   myvector.pop_back();
}

回答by Ravi Kumar Yadav

I found the most easiest way to find sum of all the elements of a vector

我找到了最简单的方法来找到向量的所有元素的总和

#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;

}

In this program, I have a vector of size 10 and are initialized by 1. I have calculated the sum by a simple loop like in array.

在这个程序中,我有一个大小为 10 的向量,初始化为 1。我已经通过一个简单的循环(如数组)计算了总和。

回答by Haresh karnan

It is easy. C++11 provides an easy way to sum up elements of a vector.

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

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