如何使用现代C++实现二维vector的矩阵转置?
用现代C++的STL算法实现矩阵转置
好问题!在现代C++里用STL算法代替朴素循环确实能让代码更简洁、更符合函数式编程的风格,下面我给你两种分别用std::transform和std::for_each实现矩阵转置的方法,附带详细解释:
方法一:使用std::transform
std::transform的核心是将一个范围的元素通过映射函数转换后,写入到另一个范围。对于矩阵转置来说,我们可以把转置后的每一行看作是原矩阵对应列的元素集合,用transform来提取原矩阵的列元素并填充到转置矩阵的行中。
完整代码示例
#include <vector> #include <algorithm> template<typename T> std::vector<std::vector<T>> transpose_with_transform(const std::vector<std::vector<T>>& original) { if (original.empty()) { return {}; } const size_t row_size = original.size(); const size_t col_size = original[0].size(); // 初始化转置矩阵:行数=原列数,列数=原行数 std::vector<std::vector<T>> transposed(col_size, std::vector<T>(row_size)); // 遍历转置矩阵的每一行(对应原矩阵的每一列) for (size_t j = 0; j < col_size; ++j) { // 用transform提取原矩阵的第j列,填充到转置矩阵的第j行 std::transform(original.begin(), original.end(), transposed[j].begin(), [j](const std::vector<T>& row) { return row[j]; // 取原矩阵每行的第j个元素 }); } return transposed; }
解释
- 首先初始化转置矩阵的结构,确保行数和列数与原矩阵互换。
- 外层循环遍历转置矩阵的行索引
j(对应原矩阵的列索引)。 std::transform遍历原矩阵的所有行,对每一行执行lambda表达式,取出该行的第j个元素,然后将结果依次写入转置矩阵的第j行中。这样就完成了原矩阵一列到转置矩阵一行的转换。
方法二:使用std::for_each
std::for_each用于对范围中的每个元素执行自定义操作。我们可以通过嵌套的for_each来遍历原矩阵的每个元素,同时记录元素的行列索引,将其赋值到转置矩阵的对应位置。
完整代码示例
#include <vector> #include <algorithm> template<typename T> std::vector<std::vector<T>> transpose_with_for_each(const std::vector<std::vector<T>>& original) { if (original.empty()) { return {}; } const size_t row_size = original.size(); const size_t col_size = original[0].size(); std::vector<std::vector<T>> transposed(col_size, std::vector<T>(row_size)); size_t row_idx = 0; // 外层for_each遍历原矩阵的每一行 std::for_each(original.begin(), original.end(), [&](const std::vector<T>& row) { size_t col_idx = 0; // 内层for_each遍历当前行的每个元素 std::for_each(row.begin(), row.end(), [&](const T& val) { transposed[col_idx][row_idx] = val; // 转置赋值:原[i][j] → 转置[j][i] ++col_idx; }); ++row_idx; }); return transposed; }
解释
- 同样先初始化转置矩阵的结构。
- 外层
for_each遍历原矩阵的每一行,用row_idx记录当前行的索引。 - 内层
for_each遍历当前行的每个元素,用col_idx记录当前列的索引,将元素赋值到转置矩阵的transposed[col_idx][row_idx]位置,正好对应转置后的坐标。
补充说明
- 这两种方法的时间复杂度和朴素循环一致,都是O(row×col),因为本质上都需要遍历矩阵的每个元素一次。
- 相比朴素循环,STL算法的写法更符合现代C++的风格,代码的可读性和可维护性更好(比如后续修改元素处理逻辑时,只需要调整lambda表达式即可)。
- 需要注意:如果原矩阵的行长度不一致(非规整矩阵),这两种方法会出现未定义行为,使用前要确保原矩阵是规整的。
内容的提问来源于stack exchange,提问作者Rocking chief
相关产品推荐
相关产品推荐

