如何总结C ++向量的元素?
寻找std::vector
中所有元素总和的好方法是什么?
假设我有一个带有几个元素的向量std::vector<int> vector
。 现在我想找到所有元素的总和。 同样的不同方式有哪些?
其实有很多方法。
int sum_of_elems = 0;
C ++ 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,即使矢量浮动,它也会累积整数。 如果您正在汇总浮点数,请将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已经提供了许多不同的(和好的)方法来做到这一点,这些都不需要在这里重复。 我想建议一种速度的替代方法。
如果你要这么做很多,你可能需要考虑对你的向量进行“分类”,这样就可以单独维护一个元素的总和(并不是实际上是由于缺少一个分类而导致的子分类向量)虚拟析构函数 - 我更多地谈论一个包含和和其中的矢量的类, 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,棘手!):
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);
我们可以使用带反向迭代器的lambda表达式的for_each
:
std::for_each(v.rbegin(), v.rend(), [&](int n) { sum_of_elements += n; });
因此,正如你所看到的那样,向量总和向量总和的方式有多种,前向向量的总和是其中的一种,其中一些更加令人兴奋,并为错误提供了更大的机会。
链接地址: http://www.djcxy.com/p/85867.html