线代一开始学起来行列式计算起来真麻烦,自己尝试用C++编代码计算N阶行列式

老师让我们课余时间利用所学编写一个程序计算1600阶行列式的值,我一开始使用归纳法的思想去想的,先编出一个二阶行列式的代码,再编一个三阶行列式,二者一组合,得到他们的共有部分,但是我发现for 结构太多了,没法进行合并,我把一开始的代码先粘上给大家一些思考。

# include <iostream>
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;
}

不过我现在又有一种启发,因为我在引入一个新的for 循环操控行列不断的重复以概括全部情况,但是每加一个 for 这种操控是有负效应的,因此我现在又有了一种想法,我们可以利用goto 函数重新调用函数,防止产生多个 for 为后期的合并造成了很大的困扰。
用 goto 函数调用for 循环,我在上面的那个程序就不体现了,不过接下来的这个程序体现了goto 函数 。
接下来的这个程序是利用的行列式计算的性质,把行列式化为上三角,利用对角线来计算,这种方法感觉挺难的,但是付诸于实现其实是很简单的。我们可以理清一下思路:无非就是,user 输入行列式,系统把对角线之下的数据均变为0。
好了,废话少说,我们直接上代码

# include <iostream>
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;
}

可以看到利用了模块化实际的思想,把这个程序的三大主干均分开了,很明显,这个程序难度最大的地方就是第三个函数(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 类型,防止小数的出现,还有一个不足我在程序中已经表明,这个程序无法运行对角线含0 元素的行列式。
之后,我还会对这个程序进行改进,对此文进行加以修改。

小靴子编写代码到时候超级不容易才有了此程序,大家留下个赞呗~(跪求)(跪求)(跪求)

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值