数值算法:accumulate、reduce、transform_reduce
使用 accumulate、reduce 和适合并行处理的 transform_reduce 汇总数值范围
数值算法:accumulate、reduce、transform_reduce 是 CoddyKit 上的免费 C++ Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C++ Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C++ Academy 课程共包含 4 节课。
<numeric> 头文件
数值算法作用于数字范围,位于 <numeric> 中。
std::accumulate
经典的归约算法。默认进行求和——传入自定义二元操作即可执行其他归约。
#include <numeric>
std::vector<int> v = {1, 2, 3, 4, 5};
int sum = std::accumulate(v.begin(), v.end(), 0);
// sum = 15自定义归约
提供一个初始值和一个二元操作。
int product = std::accumulate(v.begin(), v.end(), 1,
std::multiplies<int>{});
// product = 120初始值类型很重要
累加器类型由初始值推导得出。提供 0.0,即可将 double 值累加为 double。
std::vector<double> v = {1.5, 2.5, 3.5};
double sum_d = std::accumulate(v.begin(), v.end(), 0.0); // 7.5
int sum_i = std::accumulate(v.begin(), v.end(), 0); // truncates to 6std::reduce(C++17)
类似于 accumulate,但操作必须满足结合律和交换律,从而允许并行求值。
#include <numeric>
#include <execution>
std::vector<int> v(1000);
int sum = std::reduce(std::execution::par,
v.begin(), v.end(), 0);reduce 与 accumulate 的区别
有两个区别:
reduce可能并行运行reduce不保证操作顺序——对于 + 和 * 没有问题,但对于字符串连接等不满足结合律的操作会出错
std::transform_reduce(C++17)
在一次遍历中结合变换和归约。它比单独使用 transform 和 reduce 更快,也更具表现力。
// Dot product
std::vector<int> a = {1, 2, 3}, b = {4, 5, 6};
int dot = std::transform_reduce(
a.begin(), a.end(), b.begin(),
0,
std::plus<int>{}, // reduce
std::multiplies<int>{} // transform
);
// dot = 1*4 + 2*5 + 3*6 = 32std::inner_product
transform_reduce 的早期同类算法。计算两个范围的内积(点积)。通用性较低,但接口更简单。
std::partial_sum
将运行中的累计总和写入输出范围。
std::vector<int> v = {1, 2, 3, 4};
std::vector<int> sums(4);
std::partial_sum(v.begin(), v.end(), sums.begin());
// sums = {1, 3, 6, 10}std::adjacent_difference
partial_sum 的相反操作——写入连续元素之间的差值。
std::vector<int> v = {1, 3, 6, 10};
std::vector<int> diffs(4);
std::adjacent_difference(v.begin(), v.end(), diffs.begin());
// diffs = {1, 2, 3, 4}浮点数注意事项
对于浮点数,累加顺序很重要,因为会受到舍入影响。由于求值顺序未指定,reduce 的结果可能与 accumulate 略有不同。
实际应用场景
数值算法支持以下应用:
- 求和与乘积计算
- 统计聚合值(均值、方差)
- 线性代数中的点积和范数
- 用于前缀查询的累计和
快速检查
哪个 C++17 算法可以通过一次函数调用并行归约一个范围?
总结
<numeric> 提供 accumulate、reduce、transform_reduce、partial_sum 和 adjacent_difference,用于数值归约和前缀操作。需要并行处理时选择 reduce,需要确定顺序时选择 accumulate。
常见问题解答
「数值算法:accumulate、reduce、transform_reduce」课时是免费的吗?
是的 — 「数值算法:accumulate、reduce、transform_reduce」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C++ Academy 课程的其余内容,请升级到 CoddyKit PRO。 C++ Academy 课程共包含 4 节课。
「数值算法:accumulate、reduce、transform_reduce」这节课中我会学到什么?
使用 accumulate、reduce 和适合并行处理的 transform_reduce 汇总数值范围 你通过在浏览器中直接运行的动手代码来练习 C++ Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 C++ Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 C++ Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「数值算法:accumulate、reduce、transform_reduce」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 C++ Academy 课中编写并运行代码吗?
能。每节 C++ Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 不修改内容的算法:find、count、all_of
- 修改元素:transform、copy_if、replace
- 排序与分区:sort、stable_partition
- 数值算法:accumulate、reduce、transform_reduce