如何将 std::accumulate 用于矩阵
Posted
技术标签:
【中文标题】如何将 std::accumulate 用于矩阵【英文标题】:How to use std::acumulate for matrix 【发布时间】:2021-12-31 15:01:11 【问题描述】:#include <iostream>
#include <numeric>
#include <vector>
using matrix = std::vector<std::vector<int>>;
int main()
matrix mtx5, std::vector<int>(5);
int sum = 0;
for (const auto i : mtx) // can be avoided ?
sum += std::accumulate(i.begin(), i.end(), 0,
[](int a, int b)a > 0 ? a + b : a;);
我想将std::accumulate
用于std::vector<std::vector<int>>
,但我很好奇是否可以避免循环。另外我想知道最后一个参数是否可以。
【问题讨论】:
您可以对每个外部向量使用accumulate
,而函子将是您拥有的accumulate
,基本上,累积在accumulate 中。
【参考方案1】:
根据您的 lambda,您似乎只想对正数项求和:
#include <iostream>
#include <numeric>
#include <vector>
using Number = int;
using Matrix = std::vector<std::vector<Number>>;
int main()
Matrix mtx5, std::vector<Number>(5, 1);
Number sum_positives = std::accumulate(
mtx.begin(), mtx.end(), Number(0), [](Number const acc, auto const &v)
return std::accumulate(
v.begin(), v.end(), acc,
[](Number const a, Number const b) return b > 0 ? a + b : a; );
);
std::cout << sum_positives << std::endl; // 25
return 0;
不要忘记传递给 std::accumulate()
的 lambda 必须返回一个值。
【讨论】:
【参考方案2】:C++20 范围的join_view
s 对此特别有用,因为它们允许您将矩阵展平为向量。
所以你最终会得到如下代码:
int sum0;
auto jv std::ranges::join_view(mtx) ; // flatten mtx into a list of ints
std::ranges::for_each(jv, [&sum](auto n) sum += ((n > 0) ? n : 0); );
不幸的是,范围'accumulate
直到 C++23 才可用:
auto sum std::ranges::accumulate(jv, 0, [](auto total, auto n) return total + ((n > 0) ? n : 0); ) ;
对于用[-100, 100]
之间的随机数填充矩阵的完整样本:
[Demo]
#include <algorithm> // for_each
#include <iostream> // cout
#include <random> // default_random_engine, uniform_int_distribution
#include <ranges> // for_each, join_view
#include <vector>
using matrix = std::vector<std::vector<int>>;
int main()
matrix mtx3, std::vector<int>(3);
// Fill matrix with random values between [-100, 100]
std::default_random_engine re std::random_device() ;
std::uniform_int_distribution<int> dist -100, 100 ;
std::for_each(std::begin(mtx), std::end(mtx),
[&dist, &re](auto& row)
std::for_each(std::begin(row), std::end(row),
[&dist, &re](auto& n) n = dist(re);
);
);
auto jv std::ranges::join_view(mtx) ; // flatten mtx into a list of ints
// Print matrix
std::cout << "mtx = ";
std::ranges::for_each(jv, [](auto n) std::cout << n << " "; );
std::cout << "\n";
// Sum all positive values in the matrix
int sum0;
std::ranges::for_each(jv, [&sum](auto n) sum += ((n > 0) ? n : 0); );
std::cout << "sum = " << sum << "\n";
【讨论】:
以上是关于如何将 std::accumulate 用于矩阵的主要内容,如果未能解决你的问题,请参考以下文章
C++ STL应用与实现86: 如何使用std::accumulate