std::accumulate
对于函数式编程的定义较为广泛,大家可以去网上搜一搜
然后在开始之前,我们明确一个概念
能够接收函数作为参数或返回函数作为结果的函数成为高阶函数
C++中的仿函数,lambda表达式让C++函数式编程成为可能
对于我们今天的主角,std::accumulate,他是STL提供的一个高阶函数,可以用来计算集合中所有条目的累加和
使用方法如下
std::accumulate(array.begin(), array.end(), 0)
// 前两个参数是容器的迭代器,用于表示开头和结尾
// 第三个参数是累加的初始值,这里我们设为0
std::accumulate是一个高阶函数,我们可以通过传递一个自定义函数来改变他的行为
比如我们现在要求集合中所有元素的乘积
std::accumulate(set.begin(), set.end(), 1, std::multiplies<int>())
这里我们传入了std::multipiles<int>()
作为参数
std::accumulate是折叠(folding)或精减(reduction)的一种实现,在前面求和的例子中,std::accumulate首先计算初始值与第一个元素的和,然后再与下一个元素相加,以此类推
折叠不要求他的参数与二元函数具有相同的类型,Folding接收一个包含T类型条目的集合,以及一个类型为R的初始值
那么他的二元函数为f: (R, T) -> R
所以我们计算的过程就是((((a1 + a2) + a3) + a4) + ...)
这种类型的折叠成为左折叠,还有右折叠,我们可以通过传入rbegin() rend()
来实现右折叠
这里注意,我们需要具有左/右结合性才可以使用对应的折叠,这是因为我们需要满足a * b * c = (a * b) * c
时才可以使用左折叠,右折叠同理
最后给出一个在字符串中计算换行符的个数的例子
int f(int pre_count, char c) {
return pre_count + (c == '\n');
}
int count_lines(const std::string &s) {
return std::accumulate(
s.cbegin(), s.cend(),
0,
f
);
}
// cbegin cend为常迭代器
// 传参时要注意,第一个参数是初始值的类型,第二个参数是每个元素的类型
文章评论