
[英]C++ Find the sum of elements between minimum and maximum element of matrix
[英]sum up vectors in a matrix, element by element in c++
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]
我发现存在用于两个向量的这种方法,我想将它扩展到许多向量,特别是组成矩阵std::vector<vector<type> > M
的std::vector<type>rows
,不知道先验 M 的维数。
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 或更高版本,则可以使用折叠表达式和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
您可以为向量定义operator+=
,它允许您定义一个广义Sum
函数,该函数接收一个范围的开始和结束运算符以求和,该函数适用于具有与+=
运算符(如基本类型或(可能嵌套))一起使用的任何值类型的迭代器提供+=
运算符的类型向量:
template<typename T>
std::vector<T>& operator+=(std::vector<T>& lhs, std::vector<T> const& rhs)
{
if (lhs.empty())
{
lhs = rhs; // first summand; 0 + x = x
}
else
{
for (size_t i = 0; i < lhs.size(); ++i)
{
lhs[i] += rhs.at(i); // component-wise add
}
}
return lhs;
}
// sum up elements in a given range
template<typename IteratorType>
typename std::iterator_traits<IteratorType>::value_type Sum(IteratorType summandBegin, IteratorType summandEnd)
{
typename std::iterator_traits<IteratorType>::value_type sum {}; // 0 or object created with default constructor depending on the type
while (summandBegin != summandEnd)
{
sum += *summandBegin;
++summandBegin;
}
return sum;
}
// sums the first count elements of a vector
template<typename T>
T PartialSum(std::vector<T> const& vec, size_t count)
{
assert(vec.size() >= count);
return Sum(vec.begin(), vec.begin() + count);
}
// logic for displaying
template<typename T>
std::ostream& operator<<(std::ostream& s, std::vector<T> const& vec)
{
s << '{';
for (auto& val : vec)
{
s << val << ", ";
}
s << '}';
return s;
}
int main(int argc, char *argv[]) {
std::vector<std::vector<std::vector<int>>> matrix { {{1, 2},{ 3, 4},{ 5, 6}},{{7, 8},{ 9, 10},{11, 12}},{{13, 14},{ 15, 16},{ 17, 18}}};
auto partialSum = PartialSum(matrix, 2);
std::cout << matrix << '\n' << partialSum << '\n';
std::cout << "\nSomething extra:\n";
std::vector<std::vector<std::string>> m2 = {{"Hell" , "Wo"} , {"o ", "rld!"}, {"foo", "bar"}};
auto message = PartialSum(m2, 2);
for (auto& msg : message)
{
std::cout << msg;
}
std::cout << '\n';
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.