花了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 }