C ++中的accumulate函数是否添加负数?

问题描述

vector<int> nums={1,12,-5,-6,50,3};
int k=4;
int n=nums.size();
for(int i=0;i<=n-k;i++)
    cout<<accumulate(nums.begin()+i,nums.begin()+i+k-1,0)<<" ";

上面的代码输出为:8 1 39

问题是为什么[1,12,-5,-6]的总和为8,应为2 =(1 + 12-5-6)?

与1相同,应该为51 =(50 + 12-5-6),并且

是否与39相同,应该是42 =(50 + 3-6-5)?

解决方法

如果您实际上做了accumulate的操作-依次添加-并查看每个部分结果,您将看到

1 + 0 = 1
1 + 12 = 13
13 + -5 = 8
8 + -6 = 2

12 + 0 = 12
12 + -5 = 7
7 + -6 = 1
1 + 50 = 51

-5 + 0 = -5
-5 + -6 = -11
-11 + 50 = 39
39 + 3 = 42

在这一点上,您可能会发现accumulate的结果是前三个数字的总和,而不是四个。
然后,您大声惊叹accumulate中存在一个错误,使它无视最后一个元素。
然后,您查看文档,发现范围的末尾是“最后一个元素之后”,因此您的最终迭代器nums.begin() + i + 4 - 1表示其前面的元素(即*(begin() + i + 2)begin() + i中的第三个元素是范围内 中的最后一个元素。
标准库中的所有迭代器范围(和索引间隔)都以这种方式半开放。

解决方案是从最终迭代器中删除-1

,

如果您的假设是std::accumulate不按照常规方式处理负数,请直接进行测试

#include <iostream>
#include <vector>
#include <numeric>

int main() {
    std::vector<int> nums={1,12,-5,-6,50,3};
    std::cout << std::accumulate(nums.begin(),nums.begin() + 4,0);
}

输出为2,对应于1 + 12 - 5 - 6

问题出在您的代码中;并在您的迭代器中添加。具体来说,std::accumulate的前两个参数都相对于nums.begin():您需要从第二个参数中删除-1

,

std::accumulate的第二个参数是位置紧挨着要处理的元素。

-1中的nums.begin()+i+k-1正在阻止处理最后一个要处理的元素,因此应将其删除。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...