線代は初めから行列式の計算を学ぶのが面倒で、自分でC++コードを編んでN次行列式を計算することを試みます


先生は私达に授业の余暇に1つのプログラムを编んで1600阶の行列式の値を计算させて、私は最初に帰納法の思想を使って考えて、まず1つの2阶の行列式のコードを编んで、更に1つの3阶の行列式を编んで、2つの组み合わせて、彼らの共有部分を得て、しかし私はforの构造が多すぎて、合并することができないことを発见して、最初のコードを貼り付けて皆さんに考えてもらいました.
# include 
using namespace std;
int arrange(int arr[], int len);
int main(void)
{
     
 int time = 1;
 int sum = 0;
 int i, m, n;
 int sign = 1;
 int arr[3][3] =
 {
     
  {
     1,2,3},
  {
     4,5,6},
  {
     7,8,9}
 };
 for (m = 0; m < 3; m++)
 {
     
  for (n = 0; n < 3; n++)
  {
     
   if (n != m)
   {
     
    for (i = 0; i < 3; i++)
    {
     
     if (i != n && i != m)
     {
     
      time *= arr[0][m];
      time *= arr[1][n];
      time *= arr[2][i];
      int array[] = {
      m,n,i };
      int len = sizeof(array) / sizeof(array[0]);
      sign = arrange(array, len);
      sum += sign * time;
      time = 1;
     }
    }
   }
  }
 }
 cout << "sum = " << sum << endl;
 return 0;
}
int arrange(int arr[], int len)
{
     
 int i, j, temp;
 int count = 0;
 for (i = 0; i < len - 1; i++)
 {
     
  for (j = 0; j < len - i - 1; j++)
  {
     
   if (arr[j] > arr[j + 1])
   {
     
    temp = arr[j + 1];
    arr[j + 1] = arr[j];
    arr[j] = temp;
    count++;
   }
  }
 }
 if (count % 2)
  return -1;
 else
  return 1;
}

しかし、私は今また1つの啓発があって、私は新しいfor循環操作行列を導入して絶えず繰り返してすべての状況を概括しているため、しかし1つのforを加えるたびにこのような操作はマイナス効果があるので、私は今また1つの考えを持って、私たちはgoto関数を利用して関数を再呼び出して、複数のforが後期の合併のために大きな悩みをもたらすことを防止することができます.goto関数でforループを呼び出すと、私は上のプログラムでは体現しませんが、次のプログラムではgoto関数を体現しています.次のこのプログラムは,行列式計算の性質を利用して行列式を上三角にし,対角線で計算するという方法は難しいと感じているが,実現に移すのは簡単である.私たちは考えを整理することができます:userは行列式を入力して、システムは対角線の下のデータをすべて0に変えます.はい、くだらないことは言わないで、私たちは直接コードに行きます.
# include 
using namespace std;
# define N 4
int time = 1;
//user      
void SCANF(int arr[N][N])
{
     
 for (int i = 0; i < N; i++)
 {
     
  for (int j = 0; j < N; j++)
  {
     
   cout << "    arr[" << i << "][" << j << "]    : ";
   cin >> arr[i][j];
  }
 }
}
// user      N       
void PRINTF(int arr[N][N])
{
     
 cout << "  " << N << "     " << endl;
 for (int i = 0; i < N; i++)
 {
     
  for (int j = 0; j < N; j++)
  {
     
   cout << "\t" << arr[i][j];
  }
  cout << endl;
 }
}
//          
 // 16:33           ,       arr[0][0] = 0    ?
void TRANSFORM(int arr[N][N])
{
     
 cout << "       :" << endl;
 int n = 0;
 int count = 0;
k:
 for (int i = 0; i < N; i++)
 {
     
  for (int j = 0; j < N; j++)
  {
     
   if (i > n)
   {
     
    double m = 1.0 * arr[i][n] / arr[n][n];
    for (int t = 0; t < N; t++)
    {
     
     arr[i][t] += arr[n][t] * (-1) * m;
    }
   }
  }
  count++;
  cout << "count =  " << count << endl;
 }
 if (count < (N-1) * N)
 {
     
  n++;
  goto k;
 }
 for (int row = 0; row < N; row++)
 {
     
  for (int col = 0; col < N; col++)
  {
     
   if (row == col)
    time *= arr[row][col];
  }
 }
}
int main(void)
{
     
 int arr[N][N];
 SCANF(arr);
 PRINTF(arr);
 TRANSFORM(arr);
 PRINTF(arr);
 cout << N << "       : " << time << endl;
 return 0;
}

モジュール化された現実的な考え方を利用して,このプログラムの3つの主幹をすべて分離したことが分かるが,このプログラムが最も難易度が高いのは3つ目の関数(void TRANSFORM(int arr[N][N]))であることが明らかになった.
void TRANSFORM(int arr[N][N])
{
     
 cout << "       :" << endl;
 int n = 0;
 int count = 0;
k:
 for (int i = 0; i < N; i++)
 {
     
  for (int j = 0; j < N; j++)
  {
     
   if (i > n)
   {
     
    double m = 1.0 * arr[i][n] / arr[n][n];
    for (int t = 0; t < N; t++)
    {
     
     arr[i][t] += arr[n][t] * (-1) * m;
    }
   }
  }
  count++;
  cout << "count =  " << count << endl;
 }
 if (count < (N-1) * N)
 {
     
  n++;
  goto k;
 }
 for (int row = 0; row < N; row++)
 {
     
  for (int col = 0; col < N; col++)
  {
     
   if (row == col)
    time *= arr[row][col];
  }
 }
}

まず、先生が言った1600階の行列式の要素は0、1だけで構成されていることを明らかにします.これはこのプログラムで実行するのに当然余裕があります.本当に普段の作業用の計算機になりたいなら、このプログラムにはまだ大きな不足があり、最大の不足は誤差です.未処理のコンパイラで3*(7/3)の結果が7であることを保証できないので、将来的には上三角が本当に成功することを保証し、配列をintタイプに定義し、小数の出現を防止しなければなりません.もう1つの不足は、対角線に0要素を含む行列式を実行できないことをプログラムで示しています.その後、私はまたこのプログラムを改善して、この文を修正します.
小さい靴はコードを书いてその时とても容易でなくてやっとこのプログラムがあって、みんなは1つの賛呗を残します~(ひざまずいて求めます)(ひざまずいて求めます)