Как суммировать элементы вектора C++?

Что такое хороший способы нахождения суммы всех элементов std::vector?

Предположим у меня есть вектор std::vector<int> vector с несколькими элементами в нем. Теперь я хочу найти сумму всех элементов. Что такое разные способы для одного и того же?

8 ответов


на самом деле существует довольно много методов.

int sum_of_elems = 0;

C++03

  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, он будет накапливать ints, даже если вектор имеет плыть. Если вы суммируете числа с плавающей запятой, измените 0 to 0.0 или 0.0f (спасибо nneonneo).

C++11 и выше

  1. используя std::for_each:

    std::for_each(vector.begin(), vector.end(), [&] (int n) {
        sum_of_elems += n;
    });
    
  2. использование диапазона на основе цикла for (благодаря Роджеру Пейту):

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

Прасун уже предложил множество различных (и хороших) способов сделать это, ни один из которых не нужно повторять здесь. Однако я хотел бы предложить альтернативный подход к скорости.

Если вы собираетесь делать это совсем немного, вы можете рассмотреть вопрос о "подклассе" вашего вектора, чтобы сумма элементов поддерживалась отдельно (не на самом деле вектор подкласса, который является неопределенным из - за отсутствия виртуального деструктора- я говорю больше о классе, который содержит сумму и вектор внутри нее,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

очевидно, что это псевдо-код и вам может потребоваться немного больше функциональности, но он показывает основную идею.


Зачем выполнять суммирование вперед, когда вы можете это сделать назад? Дано:

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 (oooh, tricky!):

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 С лямбда-выражением с использованием обратных итераторов:

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

Итак, как вы можете видеть, существует столько же способов суммировать вектор назад, сколько и суммировать вектор вперед, и некоторые из них гораздо более увлекательны и предлагают гораздо больше возможностей для ошибок off-by-one.


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

только C++0x:

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

это похоже на BOOST_FOREACH, упомянутый в другом месте, и имеет то же преимущество ясности в более сложных ситуациях по сравнению с функторами с состоянием, используемыми с accumulate или for_each.


Я пользователь 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();
}

можно также использовать 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 также займет время.

в этом случае не используйте его и возьмите его как еще один способ суммирования последовательности.

спасибо


Я нашел самый простой способ найти сумму всех элементов вектор

#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. Я вычислил сумму простым циклом, как в array.