n階行列式計算----c語言實現(完結)
阿新 • • 發佈:2019-01-02
過了很久之後,加了一些註釋,若是各位看官還有不清楚的請百度去,或者直接問我,願意解答。#include <malloc.h> #include <stdio.h> #include <stdlib.h>//包含的標頭檔案不解釋 typedef bool int //因為標準c裡邊沒有bool型別才這麼做 #define false 0 #define true 1 //定義幾個全域性變數,無奈之舉 int *c, //將整個行列式的值存到c指向的空間裡 n = 0,//記錄當前的行列式計算進行了多少步 a, //方便傳遞行列式的階數 sum = 0; //記錄每一步行列式計算所累加的結果 int aq(int a) //計算階乘的函式,就不多解釋了 { int s = 1; for (int i = 1; i <= a; i ++) s *= i; return s; } void swap(int *a, int *b) //利用地址傳遞,交換兩個數的值 { int m = * a; * a = * b; *b = m; } bool sa(int *l) //計算在行列式計算過程中每一項前邊的符號是正還是負 { int n = 0;//n為行列式展開式每一項的逆序數 for (int i = 0; i < a - 1; i ++) for (int j = i + 1; j < a; j++) if (l[i] > l[j])n++; //不斷通過條件判斷累加逆序數得出最終的逆序數 if (n % 2 == 0) return false; //若為正,則返回false return true;//否則返回true } void perm(int *l, int k, int m) //整個程式裡邊的核心函式,找出在不同行不同列的所有組合 { int i, s = 1; if (k > m) { n++;//每遞歸回來一次,將記錄執行次數加一 for (int j = 0; j < a; j ++) s *= c[ l[ j ] + a * j ];//算出此次行列式展開式的這項的值 if ( sa( l ) ) s * = -1; //確定這一項的符號 //輸出當前sum內的值(即到當前為止所得到的結果是多少) //輸出執行的完成程度(即當前執行的次數除以總次數) printf("%5d 完成度:%2.2f%%\n", sum + = s, n / ( aq( a ) * 0.1 ) * 10 ); } else //不斷的向內遞迴,就不多解釋了,因為很多大公司招聘的時候,全排列問題在筆試環節是必出題,百度裡有很多解釋 { for (i = k; i <= m; i++) { swap(l + k, l + i); perm(l, k + 1, m); swap(l + k, l + i); } } } void main()//主函式 { int *b, //一個輔助變數,在遞迴函式中將b指向的空間內的值進行全排列,也即行列式展開式不同組合的下標 i, //迴圈中的輔助變數 f, //在格式化輸出行列式的輔助變數 e;//判斷是否退出程式的標誌位 system("color 3e");//設定程式執行的前景色和背景色 u: system("cls");//清空螢幕 printf("請輸入行列式的階數:\n"); scanf("%d", &a);//獲取行列式的階數 b = ( int *) malloc ( sizeof ( int ) * a ); //為變數申請空間 c = ( int *) malloc ( sizeof ( int ) * a * a ); for ( i = 0; i < a; i++) * ( b + i ) = i;//為輔助變數也即行列式下標逐個賦值 for ( i = 0; i < a * a; i++) { if ( i % a == 0 ) printf("請依次輸入行列式中第%d行的值(以空格分隔):\n", i / a + 1 ); //提示輸入行列式的值 scanf("%d", c + i ); } printf("\n\n"); perm( b, 0, a - 1 );//計算行列式的值 printf("\n行列式展開式共有%d項\n", aq( a ) );//打印出來行列式的各種資訊 if ( a % 2 != 0 ) f = a + 1;//判斷當前的行列式是偶數行還是奇數行 else f = a; for ( i = 0; i < a * a; i ++ ) { if ( i / a + 1 == f / 2 && i % a == 0) //判斷是否達到行列式中間的一行行首 printf("D = ");//輸出“D = ” else if ( i % a == 0) //判斷是否是每一行的行首,若是則輸出四個空格,保證輸出的格式優美 printf(" "); if ( i % a == 0) //判斷是否是行首,若是輸出製表符豎線,可與上一句寫到一塊兒 printf("┃"); if ( ( i + 1 ) % a == 0) //判斷是否是行列式某一行的最後一個數 printf("%2d", * ( c + i ) ); else printf("%2d ", * ( c + i ) );//若不是行列式某一行的最後一個數則在數字後邊加一個空格 if ( ( i + 1 ) % a == 0 ) //判斷是否到達一行的行末 printf("┃"); if ( ( i + 1 ) / a == f / 2 && ( i + 1 ) % a == 0) //判斷是否達到行列式中間一行的行末,輸出整個行列式的值 printf(" = %d\n", sum); else if ( ( i + 1 ) % a == 0 ) //判斷是否到達行末輸出換行 printf("\n"); } printf("\n\n"); printf("是否繼續?( 1 / 0 )\n");//提示是否退出 scanf("%d", &e); n = 0;//每次都將都將上一次的執行記錄消除 if ( e == 1 ) goto u; //判斷是否推出 else if ( e == 0 ) exit( 0 ); }