转置二维数组需先判断是否为方阵:非方阵维度改变(如3×4→4×3),须显式分配新空间;方阵可原地转置,仅遍历上三角(i<j)避免重复交换。

转置二维数组必须先确认是否为方阵
非方阵的二维数组转置后维度会变化,比如 3x4 变成 4x3,不能原地操作。C++ 中用 std::vector<:vector>></:vector> 或裸数组时,必须显式分配新空间,否则越界或静默错误。
- 方阵(
n x n)可原地转置,但需只遍历上三角(i ),避免重复交换 - 非方阵必须新建容器:目标数组行数 = 原数组列数,列数 = 原数组行数
- 裸数组(如
int a[3][4])无法直接返回转置——类型固定,不能变成int[4][3];必须用指针或封装
用 std::vector 实现通用转置函数
推荐封装成模板函数,自动推导类型和尺寸。注意:vec[i][j] 对应原矩阵第 i 行第 j 列,转置后应放在新矩阵第 j 行第 i 列。
template <typename T>
std::vector<std::vector<T>> transpose(const std::vector<std::vector<T>>& mat) {
if (mat.empty()) return {};
size_t rows = mat.size();
size_t cols = mat[0].size();
std::vector<std::vector<T>> res(cols, std::vector<T>(rows));
for (size_t i = 0; i < rows; ++i)
for (size_t j = 0; j < cols; ++j)
res[j][i] = mat[i][j];
return res;
}
这个实现兼容空行、不规则输入(只要每行长度一致),但不会校验所有行是否等长——若传入 {{1,2}, {3}},访问 mat[1][1] 会越界。实际使用前建议加 assert 或预检查。
原地转置方阵时的索引陷阱
写循环容易错写成 for (int j = 0; j ,导致每个元素被交换两次,最终回到原样。正确做法是内层循环从 <code>i+1 开始。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
立即学习“C++免费学习笔记(深入)”;
- 错误写法:
for (int j = 0; j → <code>(0,1)和(1,0)各被处理一次,再轮到(1,0)又换回去 - 正确写法:
for (int j = i + 1; j ,只交换上三角,共 <code>n*(n-1)/2次 - 裸数组原地转置示例:
std::swap(a[i][j], a[j][i]);必须确保i != j且不重复
性能与内存布局的影响
按行优先存储(C++ 默认)的二维数组,原矩阵是连续内存块,但转置后访问模式变成跨步读取(stride = 原行宽),缓存不友好。对大矩阵,这比分配新内存+顺序写入慢得多。
- 如果只是需要「逻辑转置」而非物理重排,考虑用包装类(如
TransposedView)延迟计算 - 用
std::vector时,res[j][i] = ...的写入是跳跃的,但现代编译器可能优化;若性能敏感,可改为按目标顺序填充(即外层循环列,内层循环行) - 不要试图用
reinterpret_cast强转指针来“假装”转置——维度信息丢失,类型系统失效,必出错
真正麻烦的不是写几行循环,而是想清楚:你到底需要一个新矩阵,还是只需要以转置方式访问原数据?后者往往更轻量,也更易避免拷贝和越界。

















