找到a中所有元素之和的好方法是std::vector什么?
假设我有一个std::vector<int> vector包含少量元素的向量.现在我想找到所有元素的总和.有什么不同的方式?
Pra*_*rav 400
实际上有很多方法.
int sum_of_elems = 0;
Run Code Online (Sandbox Code Playgroud)
循环经典:
for(std::vector<int>::iterator it = vector.begin(); it != vector.end(); ++it)
sum_of_elems += *it;
Run Code Online (Sandbox Code Playgroud)使用标准算法:
#include <numeric>
sum_of_elems = std::accumulate(vector.begin(), vector.end(), 0);
Run Code Online (Sandbox Code Playgroud)
旗
积累小心.最后一个参数的类型不仅用于初始值,还用于结果的类型.如果你在那里放一个int,即使向量有浮点数,它也会累积整数.如果要汇总浮点数,请更改0为0.0或0.0f(感谢nneonneo).
使用std::for_each:
std::for_each(vector.begin(), vector.end(), [&] (int n) {
sum_of_elems += n;
});
Run Code Online (Sandbox Code Playgroud)使用基于范围的for循环(感谢Roger Pate):
for (auto& n : vector)
sum_of_elems += n;
Run Code Online (Sandbox Code Playgroud)pax*_*blo 34
Prasoon已经提供了许多不同的(和好的)方法来做到这一点,这里不需要重复.不过,我想建议一种替代的速度方法.
如果你要做这么多,你可能会考虑对你的向量进行"子类化",以便单独维护一个元素的总和(实际上不是由于缺少一个元素而导致的子类向量虚拟析构函数 - 我说的更多的是一个包含sum和一个向量的类,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
Run Code Online (Sandbox Code Playgroud)
显然,这是伪代码,您可能希望获得更多功能,但它显示了基本概念.
bea*_*ker 29
最简单的方法是使用std:accumuate的vector<int> A:
#include <numeric>
cout << accumulate(A.begin(), A.end(), 0);
Run Code Online (Sandbox Code Playgroud)
Jam*_*lis 23
为什么可以向后执行向前求和?鉴于:
std::vector<int> v; // vector to be summed
int sum_of_elements(0); // result of the summation
Run Code Online (Sandbox Code Playgroud)
我们可以使用下标,向后计数:
for (int i(v.size()); i > 0; --i)
sum_of_elements += v[i-1];
Run Code Online (Sandbox Code Playgroud)
我们可以使用范围检查"下标",向后计数(以防万一):
for (int i(v.size()); i > 0; --i)
sum_of_elements += v.at(i-1);
Run Code Online (Sandbox Code Playgroud)
我们可以在for循环中使用反向迭代器:
for(std::vector<int>::const_reverse_iterator i(v.rbegin()); i != v.rend(); ++i)
sum_of_elements += *i;
Run Code Online (Sandbox Code Playgroud)
我们可以使用前向迭代器,在for循环中向后迭代(噢,棘手!):
for(std::vector<int>::const_iterator i(v.end()); i != v.begin(); --i)
sum_of_elements += *(i - 1);
Run Code Online (Sandbox Code Playgroud)
我们可以使用accumulate反向迭代器:
sum_of_elems = std::accumulate(v.rbegin(), v.rend(), 0);
Run Code Online (Sandbox Code Playgroud)
我们可以使用for_each反向迭代器使用lambda表达式:
std::for_each(v.rbegin(), v.rend(), [&](int n) { sum_of_elements += n; });
Run Code Online (Sandbox Code Playgroud)
因此,正如您所看到的,有向后向量求和向量的方法与向前求和的总和相同,其中一些方法更令人兴奋,并为逐个错误提供了更大的机会.
raf*_*fak 15
#include<boost/range/numeric.hpp>
int sum = boost::accumulate(vector, 0);
Run Code Online (Sandbox Code Playgroud)
我是Perl用户,我们的一个游戏就是找到增加变量的每种不同方式......这在这里并没有什么不同.在C++中找到向量元素总和的方法的答案可能是an infinity......
我的2美分:
使用BOOST_FOREACH,摆脱丑陋的迭代器语法:
sum = 0;
BOOST_FOREACH(int & x, myvector){
sum += x;
}
Run Code Online (Sandbox Code Playgroud)
迭代索引(真的很容易阅读).
int i, sum = 0;
for (i=0; i<myvector.size(); i++){
sum += myvector[i];
}
Run Code Online (Sandbox Code Playgroud)
另一个是破坏性的,像堆栈一样访问矢量:
while (!myvector.empty()){
sum+=myvector.back();
myvector.pop_back();
}
Run Code Online (Sandbox Code Playgroud)
小智 5
仅限C++ 0x:
vector<int> v; // and fill with data
int sum {}; // or = 0 ... :)
for (int n : v) sum += n;
Run Code Online (Sandbox Code Playgroud)
这类似于其他地方提到的BOOST_FOREACH,与使用accumulate或for_each的有状态仿函数相比,在更复杂的情况下具有相同的清晰度.
小智 5
一个人也可以std::valarray<T>这样使用
#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;
}
Run Code Online (Sandbox Code Playgroud)
有些人可能发现这种方法没有效率,因为valarray需求的大小必须与向量的大小一样大,初始化valarray也将花费一些时间。
在这种情况下,请勿使用它,并将其作为总结序列的另一种方法。