n階行列式計算----c語言實現(完結)


花了半天時間,寫了這個n階行列式計算的程序,應該算是比較優美吧,有很多地方多次做了優化,程序占用內存不是很大,要是說小吧,也不合適,因為里邊有一個遞歸,而且遞歸的深度還比較深。時間復雜度具體沒有細看,應該不會太大。
看我的程序運行的截圖:




ok,先看程序。
 
 C  Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
 
 
#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 %  ==  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/( a q( a ) *  0 . ) *  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 ==  )
            printf(
"請依次輸入行列式中第%d行的值(以空格分隔):\n" ,i / a +  );//提示輸入行列式的值
        scanf(
"%d" , c + i );
    }
    printf(
"\n\n" );
    perm( b, 
0 , a -  );//計算行列式的值
    printf(
"\n行列式展開式共有%d項\n" , aq( a ) );//打印出來行列式的各種信息
   
  if  ( a %  !=  ) f = a +  1 ;//判斷當前的行列式是偶數行還是奇數行
        
else  f = a;
    
for ( i =  0 ; i < a * a; i ++ )
    {       

        
if  ( i / a +  == f /  && i % a ==  0 ) //判斷是否達到行列式中間的一行行首
            printf(
"D = " );//輸出“D = ”
        
else   if  ( i % a ==  0 ) //判斷是否是每一行的行首,若是則輸出四個空格,保證輸出的格式優美
                    printf(
"    " );
        
if  ( i % a ==  0 ) //判斷是否是行首,若是輸出制表符豎線,可與上一句寫到一塊兒
            printf(
"┃" );
        
if  ( ( i +  ) % a ==  0 ) //判斷是否是行列式某一行的最后一個數
            printf(
"%2d" , * ( c + i ) );
        
else  printf( "%2d " , * ( c + i ) );//若不是 行列式某一行的最后 一個數則在數字后邊加一個空格
        
if  ( ( i +  ) % a ==  ) //判斷是否到達一行的行末
            printf(
"┃" );
        
if  ( ( i +  ) / a == f /  && ( i +  ) % a ==  0 ) //判斷是否達到行列式中間一行的行末,輸出整個行列式的值
            printf(
" = %d\n" ,sum);
        
else   if  ( ( i +  ) % a ==  ) //判斷是否到達行末輸出換行
                    printf(
"\n" );
    }
    printf(
"\n\n" );
    printf(
"是否繼續?( 1 / 0 )\n" );//提示是否退出
    scanf(
"%d" , &e);
    n = 0;//每次都將都將上一次的運行記錄消除
    
if ( e == goto  u;//判斷是否推出
    
else   if  ( e ==  ) exit(  );
}

 
過了很久之后,加了一些注釋,若是各位看官還有不清楚的請百度去,或者直接問我,願意解答。
里邊還有好多地方可以調整,若有更好的調整方法,請聯系我,不勝感激。 







 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM