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

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

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

Ответ 1

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

int sum_of_elems = 0;

С++ 03

  • Классический для цикла:

    for(std::vector<int>::iterator it = vector.begin(); it != vector.end(); ++it)
        sum_of_elems += *it;
    
  • Использование стандартного алгоритма:

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

    флаг

    Будьте осторожны с накоплением. Последний тип аргумента используется не только для начального значения, но и для типа результата. Если вы поместите int туда, он будет накапливать int, даже если вектор имеет float. Если вы суммируете числа с плавающей запятой, измените 0 на 0.0 или 0.0f (благодаря nneonneo).

С++ 11 и выше

  1. Использование std::for_each:

    std::for_each(vector.begin(), vector.end(), [&] (int n) {
        sum_of_elems += n;
    });
    
  2. Использование цикла, основанного на диапазоне (спасибо Roger Pate):

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

Ответ 2

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

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

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

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

Таким образом, как вы можете видеть, существует так же много способов суммирования вектора назад, как и для того, чтобы суммировать вектор вперед, а некоторые из них гораздо более захватывают и предлагают гораздо большую возможность для ошибок по отдельности.

Ответ 4

Самый простой способ - использовать std:accumuate vector<int> A:

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

Ответ 5

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

Ответ 6

Я пользователь Perl, игра, которую мы имеем, состоит в том, чтобы найти всевозможные способы увеличения переменной... что здесь совсем не так. Ответ на то, сколько способов найти сумму элементов вектора в С++, вероятно, 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();
}

Ответ 7

Только С++ 0x:

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

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

Ответ 8

Можно также использовать 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

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

#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

Это легко. С++ 11 предоставляет простой способ суммировать элементы вектора.

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