0Pricing
C++ Academy · 课时

数值算法: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 6

std::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 = 32

std::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 反馈 — 无需本地设置。

此课程中的所有课时

  1. 不修改内容的算法:find、count、all_of
  2. 修改元素:transform、copy_if、replace
  3. 排序与分区:sort、stable_partition
  4. 数值算法:accumulate、reduce、transform_reduce
← 返回 C++ Academy