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



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



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

885   8  

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

Comments

    Ничего не найдено.