如何让std::transform的结果累加至已有数组而非覆盖它?
不使用临时数组实现累加的方案
不需要额外临时数组,直接通过自定义操作或lambda表达式结合STL算法就能实现,核心思路是在遍历过程中直接完成「乘积+累加」的复合操作,避免中间存储。
方案1:使用Lambda表达式结合std::for_each
利用索引遍历,同时访问三个数组的对应元素,直接更新c的值:
long int length = 10000; double* a = new double[length]; double* b = new double[length]; double* c = new double[length]; // 初始化a、b、c的代码省略 std::for_each(std::begin(a), std::end(a), [&, idx = 0](const double& val_a) mutable { c[idx] += val_a * b[idx]; idx++; });
或者更直观的索引循环(本质和算法等价,适合习惯直接操作索引的场景):
for (long int i = 0; i < length; ++i) { c[i] += a[i] * b[i]; }
方案2:自定义仿函数结合std::transform
如果偏好使用std::transform,可以自定义一个捕获c指针的仿函数,确保迭代器同步前进:
struct AccumulateProduct { double* c_ptr; AccumulateProduct(double* c) : c_ptr(c) {} double operator()(const double& a_val, const double& b_val) { return *c_ptr++ += a_val * b_val; } }; // 使用时: std::transform(a, a+length, b, c, AccumulateProduct(c));
这里std::transform会将每个a[i]*b[i]的结果累加到c[i],同时返回更新后的c[i]完成赋值(实际内部已通过+=完成累加逻辑)。
方案3:C++20及以上使用std::views::zip
如果使用C++20或更高版本,可借助范围库的zip视图同时打包三个数组的元素,遍历逻辑更简洁:
#include <ranges> for (auto [val_a, val_b, val_c] : std::views::zip(a, a+length, b, b+length, c, c+length)) { val_c += val_a * val_b; }
注意事项
- 所有方案内存开销均为O(1)(仅算法本身栈开销),无需额外分配临时数组,直接在原
c数组上完成更新。 - 自定义仿函数方案需确保
c的迭代器与a、b的迭代器同步前进,避免数组越界。
内容的提问来源于stack exchange,提问作者张亦弛
相关产品推荐
相关产品推荐

