累积没有给出我的矢量的正确总和

Accumulate not giving correct sum of my vector

我有这个问题:

int nCab = 11;
int nCabCombo;
std::vector<int>counter(nCab);
for(int i = nCab; i > 0; i--)
{
    counter[i] = i-1;
    std::cout<<counter[i]<<std::endl;
}
nCabCombo = std::accumulate(counter.begin(),counter.end(),0);
std::cout<<nCabCombo<<std::endl;

nCabCombo 的输出是 45,而它应该是 55,出于某种原因,accumulate 函数没有添加我的计数器向量索引 11 处的 10。有人可以告诉我我在这里做错了什么吗?谢谢!

counter[i] = i-1; //when i == 11, this is an off by one error

一个数组,并扩展为一个向量,范围是 [0, size)。如果它有 nCab 个元素,则最大索引只有 nCab - 1。您正在将最后一个元素存储在向量边界之外。您应该将其更改为:

 counter[i - 1] = i-1;

缺少的元素应该是 10。当 accumulate 运行时,这就是为什么您的总和会减少 10

您没有索引 11。向量中有 11 个元素,这意味着有效索引为 [0, 10]counter[i] = i-1; 是未定义的行为,因为您访问的是向量末尾之后的行为。

忽略 UB 你的向量实际上包含 {0,0,1,2,3,4,5,6,7,8,9} 即 45

注意:它不包含 -1 的原因是 for 循环针对 i > 0 运行,因此 i 永远不会是 0 并且我们永远不会设置向量的第一个元素,因此它从向量的构造中保留 0

如其他人所述,您正在越界访问元素。

但是,您可以使用 std::iota:

而不是编写循环并陷入此类麻烦
#include <vector>
#include <algorithm>

int main()
{
    int nCab = 11;
    std::vector<int>counter(nCab);
    std::iota(counter.begin(), counter.end(), 0);
    //...
}

Live Example


如果出于某种原因你真的想循环并反向填充数组(高索引到低索引),你可以使用 std::generate 并使用反向迭代器:

#include <vector>
#include <algorithm>

int main()
{
    int nCab = 11;
    std::vector<int>counter(nCab);
    int i = 11;
    std::generate(counter.rbegin(), counter.rend(), [&i] {return --i;});
    //...
}

Live Example (std::generate)