C++ 中是否有一种简单的方法可以逐个元素地总结构成矩阵元素的向量?我的意思是,如果我有矩阵 M[3][4],我想要 sum[3] 向量与这个组件:
sum[0]=M[0][0]+M[1][0]+M[2][0]
sum[1]=M[0][1]+M[1][1]+M[2][1]
sum[2]=M[0][2]+M[1][2]+M[2][2]
很遗憾,C++标准库中没有简单的方法可以添加
容器的元素列。
有std::accumulate(),但很自然,它会将行元素加在一起,而不是列元素,但我们可以通过遍历矩阵内的每个列索引并加起来来解决这个问题元素一一:
#include <iostream>
#include <numeric>
#include <cstddef>
#include <vector>
// The below function assumes that all columns of your matrix have the same length
template <typename T>
std::vector<T> m_col_add(std::vector<std::vector<T>> const& mat) {
std::vector<T> res;
const auto column_size = mat[0].size();
for (size_t x = 0; x < column_size; ++x)
res.push_back(std::accumulate(mat.begin(), mat.end(), T{}, [x](T const& a, std::vector<T> const& row) {
return a + row[x];
}));
return res;
}
int main() {
std::vector<std::vector<int>> mat {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
auto res = m_col_add(mat);
for (auto const& elem : res)
std::cout << elem << " ";
}
输出:
15 18 21 24
或者,如果您在编译时已经知道行和列的大小,并且使用的是 C++17 或更高版本,则可以使用fold expressions 和std::index_sequence<> 相加通过编译时扩展使元素更快:
#include <iostream>
#include <utility>
#include <cstddef>
#include <array>
template <size_t Column, typename T, size_t Rows, size_t Columns, size_t ...Sizes>
T m_col_add_impl2(std::index_sequence<Sizes...>, std::array<std::array<T, Columns>, Rows> const& mat) {
return (mat[Sizes][Column] + ...);
}
template <typename T, size_t Rows, size_t Columns, size_t ...Sizes>
std::array<T, Columns> m_col_add_impl1(std::index_sequence<Sizes...>, std::array<std::array<T, Columns>, Rows> const& mat) {
std::array<T, Columns> sum;
((sum[Sizes] = m_col_add_impl2<Sizes>(std::make_index_sequence<Rows>(), mat)), ...);
return sum;
}
template <typename T, size_t Rows, size_t Columns>
std::array<T, Columns> m_col_add(std::array<std::array<T, Columns>, Rows> const& mat) {
return m_col_add_impl1(std::make_index_sequence<Columns>(), mat);
}
int main() {
std::array mat {
std::array {1, 2, 3, 4},
std::array {5, 6, 7, 8},
std::array {9, 10, 11, 12}
};
auto res = m_col_add(mat);
for (auto const& elem : res)
std::cout << elem << " ";
}
输出:
15 18 21 24