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

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

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


Actually there are quite a few methods.

int sum_of_elems = 0;

C++03

  • Classic for loop:

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

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

    flag

    Be careful with accumulate. The last argument's type is used not just for the initial value, but for the type of the result as 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 0 to 0.0 or 0.0f (thanks to nneonneo).

  • C++11 and higher

  • Using std::for_each :

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

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

  • 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.

    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 actually sub-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-a rather than is-a , and provides the vector-like methods).

    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, anything that 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.

    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.


    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(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(std::vector<int>::const_iterator i(v.end()); i != v.begin(); --i)
        sum_of_elements += *(i - 1);
    

    We can use accumulate with reverse iterators:

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

    We can use for_each with a lambda expression using reverse iterators:

    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.

    链接地址: http://www.djcxy.com/p/85868.html

    上一篇: 检查一个std :: vector是否包含某个对象?

    下一篇: 如何总结C ++向量的元素?