找出std::vector中所有元素的和的好方法是什么?
假设我有一个向量std::vector<int> vector,其中有几个元素。现在我要求所有元素的和。同样的东西有什么不同的表达方式?
找出std::vector中所有元素的和的好方法是什么?
假设我有一个向量std::vector<int> vector,其中有几个元素。现在我要求所有元素的和。同样的东西有什么不同的表达方式?
当前回答
既然可以倒着做求和,为什么还要往前做呢?考虑到:
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循环中使用前向迭代器,向后迭代(哦,很棘手!):
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与lambda表达式一起使用:
std::for_each(v.rbegin(), v.rend(), [&](int n) { sum_of_elements += n; });
所以,正如你所看到的,向后求和的方法和正向求和的方法一样多,其中一些更令人兴奋,并且提供了更大的机会出现差1的错误。
其他回答
prason已经提供了许多不同的(而且很好的)方法来做到这一点,这里没有一个需要重复。不过,我想建议另一种提高速度的方法。
如果你要经常这样做,你可能想要考虑“子类化”你的vector,这样元素的和就被分开维护(实际上不是子类化vector,因为缺少虚析构函数而存在问题——我说的更多的是一个包含和和和的类,has-a而不是is-a,并提供类似vector的方法)。
对于空向量,和设为零。每次插入向量时,将插入的元素加到和中。在每次删除时,减去它。基本上,任何可能改变底层向量的东西都会被拦截,以确保总和保持一致。
这样,您就有了一个非常有效的O(1)方法来“计算”任何时间点的和(只返回当前计算的和)。插入和删除将花费稍长的时间来调整总数,您应该考虑到这种性能影响。
如果向量的和比向量的改变更频繁,那么这些向量可能会从这个方案中受益,因为计算和的成本会在所有访问中摊销。显然,如果你只需要每小时求和,而向量每秒变化3000次,这是不合适的。
这样就足够了:
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
显然,这是伪代码,您可能希望有更多的功能,但它显示了基本概念。
我是一个Perl用户,我们有一个游戏是找到各种不同的方法来增加一个变量…这里没有什么不同。在c++中,有多少种方法可以求出一个向量元素的和,答案可能是无穷大……
我的观点是:
使用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];
}
另一个是破坏性的,像访问堆栈一样访问vector:
while (!myvector.empty()){
sum+=myvector.back();
myvector.pop_back();
}
这很简单。c++ 11提供了一种简单的方法来对一个向量的元素求和。
sum = 0;
vector<int> vec = {1,2,3,4,5,....}
for(auto i:vec)
sum+=i;
cout<<" The sum is :: "<<sum<<endl;
既然可以倒着做求和,为什么还要往前做呢?考虑到:
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循环中使用前向迭代器,向后迭代(哦,很棘手!):
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与lambda表达式一起使用:
std::for_each(v.rbegin(), v.rend(), [&](int n) { sum_of_elements += n; });
所以,正如你所看到的,向后求和的方法和正向求和的方法一样多,其中一些更令人兴奋,并且提供了更大的机会出现差1的错误。
c++ 0 x只:
vector<int> v; // and fill with data
int sum {}; // or = 0 ... :)
for (int n : v) sum += n;
这类似于其他地方提到的BOOST_FOREACH,与与accumulate或for_each一起使用的有状态函子相比,在更复杂的情况下具有同样的清晰性。