C++实现矩阵伴随矩阵遇输出顺序错误及显示函数问题
问题定位与解决方案
核心原因
你遇到的输出行列颠倒问题,本质是display函数的遍历顺序错误:调试确认Ad矩阵存储正确,但打印时按列优先而非行优先输出,导致行列反转。
修正方案
1. 修复display函数的遍历逻辑
如果你的原display函数是列循环在外、行循环在内的错误写法,直接调换循环顺序,改为行循环在外,列循环在内,即可按正常行列顺序打印:
错误写法示例:
// 错误:先列后行,导致输出行列颠倒 void display(int n, float Ad[][n]) { for (int j = 0; j < n; j++) { for (int i = 0; i < n; i++) { printf("%.2f ", Ad[i][j]); } printf("\n"); } }
修正后的正确写法:
// 正确:先行后列,按行输出每行元素 void display(int n, float Ad[][n]) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { printf("%.2f ", Ad[i][j]); } printf("\n"); } }
2. 确认伴随矩阵生成逻辑正确性
伴随矩阵是代数余子式矩阵的转置,需要确保adjoint函数中完成了转置存储:
- 先计算元素
(i,j)的代数余子式:C[i][j] = (-1)^(i+j) * 余子式M[i][j] - 转置存储到伴随矩阵:
Ad[j][i] = C[i][j]
如果这一步逻辑正确,再配合修正后的display函数,就能正确输出伴随矩阵。
完整可运行示例代码
以3x3矩阵为例,包含正确的伴随矩阵生成、打印及逆矩阵计算:
#include <stdio.h> #include <math.h> // 计算指定位置的余子式 float getCofactor(float mat[][3], int n, int row, int col) { float temp[3][3]; int ti = 0, tj = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (i != row && j != col) { temp[ti][tj++] = mat[i][j]; tj = (tj == n-1) ? 0 : tj; ti = (tj == 0) ? ti+1 : ti; } } } return temp[0][0] * temp[1][1] - temp[0][1] * temp[1][0]; } // 生成伴随矩阵 void adjoint(float mat[][3], int n, float Ad[][3]) { if (n == 1) { Ad[0][0] = 1; return; } int sign; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { sign = ((i+j) % 2 == 0) ? 1 : -1; // 转置存储:Ad[j][i] 对应代数余子式C[i][j] Ad[j][i] = sign * getCofactor(mat, n, i, j); } } } // 正确的矩阵打印函数 void display(int n, float mat[][3]) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { printf("%.2f ", mat[i][j]); } printf("\n"); } } // 计算矩阵行列式 float determinant(float mat[][3], int n) { if (n == 1) return mat[0][0]; float det = 0; int sign = 1; for (int j = 0; j < n; j++) { det += sign * mat[0][j] * getCofactor(mat, n, 0, j); sign *= -1; } return det; } // 计算逆矩阵 void inverse(float mat[][3], int n, float inv[][3]) { float det = determinant(mat, n); if (det == 0) { printf("矩阵不可逆,行列式为0\n"); return; } float Ad[3][3]; adjoint(mat, n, Ad); printf("伴随矩阵:\n"); display(n, Ad); // 伴随矩阵除以行列式得到逆矩阵 for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { inv[i][j] = Ad[i][j] / det; } } } int main() { float mat[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 10}}; // 可逆矩阵示例 float inv[3][3]; inverse(mat, 3, inv); printf("\n逆矩阵:\n"); display(3, inv); return 0; }
关键验证点
- 运行代码后,伴随矩阵的输出会和代数余子式矩阵的转置一致,无行列颠倒问题。
- 逆矩阵计算结果可通过与原矩阵相乘验证是否为单位矩阵。
内容的提问来源于stack exchange,提问作者John Mike
相关产品推荐
相关产品推荐

