C语言计算逆矩阵
花了4天写的,不过三天在重学线代。
1 #include<stdio.h> 2 #include<stdlib.h> // 操作内存 3 #include<math.h> // pow()函数,计算-1的n次方,可以不用这个函数,偷懒使用现成的 4 5 /* 6 显示矩阵 7 matrix: 矩阵 8 order: 阶数 9 */ 10 void showMatrix(float** matrix, int order) 11 { 12 for (int i = 0; i < order; i++) { 13 for (int j = 0; j < order; j++) { 14 printf(" %f ", matrix[i][j]); 15 } 16 printf("|\n"); 17 } 18 } 19 20 /* 21 交换两行 22 一开始想使用初等行变换计算,此函数可以删除,用不到 23 x1:调换第一行 24 x2:调换第二行 25 order:矩阵阶数 26 matrix:矩阵 27 */ 28 void replaceRow(int x1, int x2, int order, float **matrix) 29 { 30 float temp; 31 x1 -= 1; 32 x2 -= 1; 33 for (int i = 0; i < order; i++) { 34 temp = matrix[x1][i]; 35 matrix[x1][i] = matrix[x2][i]; 36 matrix[x2][i] = temp; 37 } 38 } 39 40 /* 41 转置矩阵 42 matrix: 矩阵 43 order: 阶数 44 */ 45 void transposeMatrix(float** matrix, int order) 46 { 47 float temp; 48 for (int i = 0; i < order; i++) { 49 for (int j = 0; j < i; j++) { 50 temp = matrix[i][j]; 51 matrix[i][j] = matrix[j][i]; 52 matrix[j][i] = temp; 53 } 54 } 55 } 56 57 /* 58 获取除了某行某列的矩阵 59 oldmatrix: 原本矩阵 60 newmatrix: 新矩阵 61 row: 要删除行 62 col: 要删除列 63 order: 阶数 64 */ 65 void get(float** oldmatrix, float** newmatrix, int row, int col, int order) 66 { 67 // 删除了一行一列,所以新矩阵行列均比原矩阵少1 68 int a = 0, b = 0; 69 int x, y, z = 0, w = 0; 70 // i,j循环原矩阵 71 for (int i = 0; i < order - 1; i++) { 72 for (int j = 0; j < order - 1; j++) { 73 // z,w代表行列的是否加一状态,防止多次加一,+1只需要1次 74 if (i >= row && z == 0) { a += 1; z = 1; } 75 if (j >= col && w == 0) { b += 1; w = 1; } 76 77 newmatrix[i][j] = oldmatrix[i+a][j+b]; 78 } 79 a = 0;b = 0; 80 z = 0;w = 0; 81 } 82 } 83 84 /* 85 计算行列式 86 matrix: 矩阵 87 order: 阶数 88 */ 89 float calc(float** matrix, int order) 90 { 91 // 递归求行列式值 92 float num=0; 93 int i, j; 94 if (order == 2) { 95 // 如果是二阶直接获取值 96 num = matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]; 97 } 98 else { 99 // 创建更小二维数组 100 order -= 1; 101 float** matrixlow = (float**)malloc(sizeof(float*) * order); 102 for (i = 0; i < order; i++) { 103 matrixlow[i] = (float*)malloc(sizeof(float) * order); 104 } 105 order += 1; 106 107 // 循环展开第一行 108 for (j = 0; j < order; j++) { 109 110 get(matrix, matrixlow, 0, j, order); 111 // 此处开始递归,调用自身函数 112 num += matrix[0][j] * pow(-1, j) * calc(matrixlow, order - 1); 113 } 114 115 // 释放内存 116 for (i = 0; i < order-1; ++i)free(*(matrixlow + i)); 117 } 118 119 return num; 120 } 121 122 123 /* 124 主函数 125 */ 126 int main() 127 { 128 int order; // 矩阵阶数 129 int i, j; 130 float det; 131 132 // 获取矩阵阶 133 printf("输入矩阵阶:"); 134 scanf("%d", &order); 135 136 printf("输入的阶是:%d\n\n", order); 137 138 // 申请二维数组内存 139 float** matrix = (float**)malloc(sizeof(float*) * order); 140 for (i = 0; i < order; i++) { 141 matrix[i] = (float*)malloc(sizeof(float) * order); 142 } 143 144 // 获取输入 145 for (i = 0; i < order; i++) { 146 for (j = 0; j < order; j++) { 147 printf("位置:( %d , %d)请输入数据:",i + 1,j + 1); 148 scanf("%f", &matrix[i][j]); 149 } 150 } 151 152 // 计算并显示det 153 det = calc(matrix, order); 154 printf("\ndet值为:%f",det); 155 // 0不能做除数 156 if (det == 0) 157 printf("\n矩阵接近奇异值,结果可能不准确!"); 158 printf("\n\n"); 159 160 // 显示输入矩阵 161 printf("\n输入的矩阵是:\n\n"); 162 showMatrix(matrix, order); 163 164 // 申请二维数组存储结果 165 float** Rmatrix = (float**)malloc(sizeof(float*) * order); 166 for (i = 0; i < order; i++) { 167 Rmatrix[i] = (float*)malloc(sizeof(float) * order); 168 } 169 170 171 // 开始计算 172 if (order == 2) { 173 // 阶数为二直接运行公式 174 float n = 1 / (matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]); 175 Rmatrix[0][0] = n * matrix[1][1]; 176 Rmatrix[0][1] = -n * matrix[0][1]; 177 Rmatrix[1][0] = -n * matrix[1][0]; 178 Rmatrix[1][1] = n * matrix[0][0]; 179 } 180 else { 181 // 转置矩阵并显示 182 transposeMatrix(matrix, order); 183 printf("\n\n转置后为:\n\n"); 184 showMatrix(matrix, order); 185 186 // 循环求i,j位的代数余子式 187 for (i = 0; i < order; i++) { 188 for (j = 0; j < order; j++) { 189 // 申请二维数组 190 order -= 1; 191 float** matrixlow = (float**)malloc(sizeof(float*) * order); 192 for (int t = 0; t < order; t++) { 193 matrixlow[t] = (float*)malloc(sizeof(float) * order); 194 } 195 order += 1; 196 197 // 获取除了i,j行的值组成行列式 198 get(matrix, matrixlow, i, j, order); 199 // 计算行列式值除以det 200 Rmatrix[i][j] = pow(-1, i + j) * calc(matrixlow, order - 1) / det; 201 202 // 释放内存 203 for (int t = 0; t < order-1; ++t)free(*(matrixlow + t)); 204 } 205 } 206 207 } 208 209 // 显示逆矩阵 210 printf("\n\n逆矩阵为:\n\n"); 211 showMatrix(Rmatrix, order); 212 213 214 //// 释放二维数组 215 for (i = 0; i < order; ++i)free(*(matrix + i)); 216 for (i = 0; i < order; ++i)free(*(Rmatrix + i)); 217 218 return 0; 219 }