Каковы хорошие способы найти сумму всех элементов в std::vector
?
Предположим, что у меня есть вектор std::vector<int> vector
с несколькими элементами в нем. Теперь я хочу найти сумму всех элементов. Каковы разные способы для этого?
Каковы хорошие способы найти сумму всех элементов в std::vector
?
Предположим, что у меня есть вектор std::vector<int> vector
с несколькими элементами в нем. Теперь я хочу найти сумму всех элементов. Каковы разные способы для этого?
На самом деле существует довольно много методов.
int sum_of_elems = 0;
Классический для цикла:
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).
Использование std::for_each
:
std::for_each(vector.begin(), vector.end(), [&] (int n) {
sum_of_elems += n;
});
Использование цикла, основанного на диапазоне (спасибо Roger Pate):
for (auto& n : vector)
sum_of_elems += n;
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
Очевидно, что этот псевдокод и вам может потребоваться немного больше функциональности, но он показывает основную концепцию.
Зачем выполнять суммирование вперед, когда вы можете сделать это назад? Дано:
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; });
Таким образом, как вы можете видеть, существует так же много способов суммирования вектора назад, как и для того, чтобы суммировать вектор вперед, а некоторые из них гораздо более захватывают и предлагают гораздо большую возможность для ошибок по отдельности.
Самый простой способ - использовать std:accumuate
vector<int> A
:
#include <numeric>
cout << accumulate(A.begin(), A.end(), 0);
#include<boost/range/numeric.hpp>
int sum = boost::accumulate(vector, 0);
Я пользователь 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();
}
Только С++ 0x:
vector<int> v; // and fill with data
int sum {}; // or = 0 ... :)
for (int n : v) sum += n;
Это похоже на BOOST_FOREACH, упомянутый в другом месте, и имеет то же преимущество ясности в более сложных ситуациях, по сравнению с функторами состояния, используемыми с накоплением или for_each.
Можно также использовать 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. Я вычислил сумму простым циклом, как в массиве.
Это легко. С++ 11 предоставляет простой способ суммировать элементы вектора.
sum = 0;
vector<int> vec = {1,2,3,4,5,....}
for(auto i:vec)
sum+=i;
cout<<" The sum is :: "<<sum<<endl;