如何总结一个C ++向量的元素?
寻找std::vector
中所有元素总和的好方法是什么?
假设我有一个有几个元素的向量std::vector<int> vector
。 现在我想find所有元素的总和。 同样的方法有什么不同?
其实有不less方法。
int sum_of_elems = 0;
C ++ 03
-
经典for循环:
for(std::vector<int>::iterator it = vector.begin(); it != vector.end(); ++it) sum_of_elems += *it;
-
使用标准algorithm:
#include <numeric> sum_of_elems = std::accumulate(vector.begin(), vector.end(), 0);
旗
小心累积。 最后一个参数的types不仅用于初始值,而且用于结果的types。 如果你在那里放置一个int,那么即使vector浮动,它也会累积整数。 如果您正在汇总浮点数,请将
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循环(感谢Roger Pate):
for (auto& n : vector) sum_of_elems += n;
Prasoon已经提出了许多不同的(好的)方法来做到这一点,这些都不需要重复。 我想build议速度的另一种方法,但是。
如果你要这么做,你可能需要考虑对你的向量进行“分类”,以便单独维护一个元素的总和(而不是实际上是由于缺less一个分类而导致的子分类向量虚拟析构函数 – 我正在谈论更多的一个类,其中包含总和和一个向量, has-a
而不是is-a
,并提供向量的方法)。
对于空向量,总和设置为零。 在vector的每个插入中,将插入的元素添加到总和中。 在每一个删除,减去它。 基本上, 任何可以改变底层向量的东西都被拦截,以确保总和保持一致。
这样,你就有一个非常高效的O(1)方法来“计算”任何时间点的总和(只是返回当前计算的总和)。 插入和删除将花费更长的时间,因为你调整了总数,你应该考虑到这个性能。
比vector更经常需要的vector的vector是可能从该scheme中受益的vector,因为计算总和的成本在所有访问中被摊销。 很显然,如果你每小时只需要一笔钱,而每秒钟换三千次,那就不合适了。
像这样的东西就足够了:
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
显然,这是伪代码,你可能想要多一点function,但它显示了基本的概念。
为什么要向前进行总结呢? 鉴于:
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
和使用反向迭代器的lambdaexpression式:
std::for_each(v.rbegin(), v.rend(), [&](int n) { sum_of_elements += n; });
所以,正如你所看到的那样,向量总和向量的总和方向向量总和方向向量的总和方向向量总和的方向有多less,其中一些方法更加令人兴奋,并且提供了更大的机会来处理逐个错误。
#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类似,与用于累积或for_each的有状态仿函数相比,在更复杂的情况下具有相同的清晰度。
我是一个Perl用户,我们有一个游戏是find各种不同的方式来增加一个variables…这里没有什么不同。 有多less种方法可以findC ++中的vector元素总和的答案可能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(); }