More than code

More Than Code
The efficiency of your iteration of reading, practicing and thinking decides your understanding of the world.
  1. 首页
  2. daily
  3. 正文

Daily C/C++ std::accumulate

2021年5月18日 652点热度 0人点赞 0条评论

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为常迭代器
// 传参时要注意,第一个参数是初始值的类型,第二个参数是每个元素的类型
标签: c++
最后更新:2021年5月20日

sheep

think again

点赞
< 上一篇
下一篇 >

文章评论

取消回复

COPYRIGHT © 2021 heavensheep.xyz. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS