Как суммировать элементы вектора C ++? - PullRequest
202 голосов
/ 11 июля 2010

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

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

Ответы [ 10 ]

378 голосов
/ 11 июля 2010

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

int sum_of_elems = 0;

C ++ 03

  1. Classic для цикла:

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

    flag

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

C ++ 11 и выше

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

std::for_each(vector.begin(), vector.end(), [&] (int n) {
    sum_of_elems += n;
});

Использование основанного на диапазоне цикла for (благодаря Роджеру Пейту):

for (auto& n : vector)
    sum_of_elems += n;
30 голосов
/ 11 июля 2010

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

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

23 голосов
/ 11 июля 2010

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

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

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

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

18 голосов
/ 07 октября 2018

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

#include <numeric>
cout << accumulate(A.begin(), A.end(), 0);
14 голосов
/ 06 августа 2010
#include<boost/range/numeric.hpp>
int sum = boost::accumulate(vector, 0);
5 голосов
/ 12 июля 2010

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

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

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

5 голосов
/ 11 июля 2010

Я - пользователь 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();
}
2 голосов
/ 05 декабря 2017

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

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

Спасибо

0 голосов
/ 16 января 2019

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

sum = 0; 
vector<int> vec = {1,2,3,4,5,....}
for(auto i:vec) 
   sum+=i;
cout<<" The sum is :: "<<sum<<endl; 
0 голосов
/ 24 июня 2018

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...