C++中用vector实现二维矩阵转置遇问题,求错误分析与替代方案
嘿,我来帮你排查这段矩阵转置代码的问题,再给你几个实用的实现思路~
你的代码里的核心错误
- 转置矩阵未初始化大小:
trans_vec一开始是空的二维vector,直接用trans_vec[j][i]去赋值会访问不存在的内存,大概率导致程序崩溃或者出现乱码。 - 没有将结果同步回原矩阵:函数接收的是原矩阵的引用
b,但你只在函数内部创建了转置后的trans_vec,却没把它赋值给b,所以主函数里的v1完全没被修改。 - 循环维度逻辑搞反了:原矩阵是2行3列,转置后应该是3行2列。你原来的循环是按原矩阵的行和列遍历,但转置矩阵的行对应原矩阵的列,列对应原矩阵的行,循环顺序得调整。
修正后的可运行代码
我把你的代码改好了,你可以直接运行看看效果:
#include <iostream> #include <vector> using namespace std; void transpose(vector<vector<int> > &b) { // 先确定原矩阵的行列数(假设矩阵是规整的,每行长度一致) int rows = b.size(); int cols = b[0].size(); // 初始化转置矩阵的大小:原列数为行数,原行数为列数 vector<vector<int> > trans_vec(cols, vector<int>(rows)); // 正确遍历原矩阵,赋值给转置矩阵 for(int i=0; i<rows; i++) { for(int j=0; j<cols; j++) { trans_vec[j][i] = b[i][j]; } } // 将转置结果赋值回原矩阵 b = trans_vec; } int main() { vector<vector<int> > v1; for(int i=0;i<2;i++) { vector<int> temp; for(int j=0;j<3;j++) { temp.push_back(i); } v1.push_back(temp); } cout << "原矩阵:" << endl; for(int i=0;i<v1.size();i++) { for(int j=0;j<v1[i].size();j++) { cout << v1[i][j] << " "; } cout<<endl; } transpose(v1); cout << "\n转置后的矩阵:" << endl; for(int i=0;i<v1.size();i++) { for(int j=0;j<v1[i].size();j++) { cout << v1[i][j] << " "; } cout<<endl; } return 0; }
其他实用的实现方法
方法1:返回新矩阵(不修改原矩阵,更安全)
这种方式不会改动原矩阵,直接返回一个新的转置矩阵,适合不需要保留原矩阵的场景:
vector<vector<int>> transpose(const vector<vector<int>>& mat) { int rows = mat.size(); int cols = mat[0].size(); vector<vector<int>> res(cols, vector<int>(rows)); for (int i = 0; i < rows; ++i) { for (int j = 0; j < cols; ++j) { res[j][i] = mat[i][j]; } } return res; } // 主函数调用示例: // vector<vector<int>> transposed_v1 = transpose(v1);
方法2:支持非规整矩阵(每行长度不同)
如果你的矩阵可能存在每行元素数量不一样的情况,可以用这个版本,会自动补0填充到最长行的长度:
vector<vector<int>> transpose(const vector<vector<int>>& mat) { // 先找到矩阵中最长的行的长度 size_t max_col_count = 0; for (const auto& row : mat) { if (row.size() > max_col_count) { max_col_count = row.size(); } } // 初始化转置矩阵的行 vector<vector<int>> res(max_col_count); for (const auto& row : mat) { for (size_t j = 0; j < row.size(); ++j) { res[j].push_back(row[j]); } // 给长度不足的行补0 for (size_t j = row.size(); j < max_col_count; ++j) { res[j].push_back(0); } } return res; }
方法3:用C++20标准库快速实现
如果你用的是C++20或更高版本,可以直接用标准库的std::views::transpose,一行代码搞定转置:
#include <ranges> #include <iostream> #include <vector> int main() { vector<vector<int>> v1 = {{0,0,0}, {1,1,1}}; // 生成转置视图(不会复制数据,效率很高) auto transposed_view = v1 | std::views::transpose; cout << "转置后的矩阵:" << endl; for (const auto& row : transposed_view) { for (int val : row) { cout << val << " "; } cout << endl; } return 0; }
内容的提问来源于stack exchange,提问作者Saptaparnee
相关产品推荐
相关产品推荐

