C++ 代码实现定义法计算行列式的值

一、前言

         最近在捣鼓C++,学到线代的行列式之后就想着来捣鼓一下求行列式的值。主要原因是当时群里有人在捣鼓着用上下三角来求值,所以我最后就去玩定义法求值了。

二、n阶行列式的定义

         从定义中我们可以看出值计算公式由三个部分组成:分别是逆序数r,行列式中n项的相乘并相加,以及全排列 j1 、j2 、j3......jn。

 三、代码实现

 1.首先我们先构架好基本框架:

#include <iostream>
#include <cmath>
using namespace std;

const int u = 10;            //最大阶数限制

int main() 
{

    int finalanswer;
    int arr[u][u];

    cout << "请输入行列式的阶数" << endl;
    cin >> n;

    for (int i = 0; i < n; i++)                           //给行列式的每项进行赋值 
    {
        cout << endl;
        for (int h = 0; h < n; h++)
        {
            cout << "a" << i + 1 << h + 1 << " 的值:";
            cin >> arr[i][h];
        }
    }

}

        cmath的头文件是因为接下来的逆序数需要用到pow(或者你也可以用for循环?)

2.排列数

int a[u];        //需要进行排列的数的数组

for (i = 0; i < n; i++)         //给排列赋值
{
     a[i] = i + 1;
}

          定义中的j1,j2,jn就是排列数,通过排列数来最后得出所需要相加的所有的项的值。

3.逆序数

int Reverse(int n, int a[])                 //逆序数
{
    int t = 0;
    for (int i = 1; i < n; i++)
    {
        for (int h = 0; h < i; h++)
        {
            if (a[i]<a[h])
            {
                t = t + 1;
            }
        }
    }
    return t;
}

        逆序数的算法比较简单,只需要用两层for检测某一位的数的前几位有多少数比他大即可。

4.求全排列

void Perm(int start, int end, int a[])        start=0  end为行列式阶数
{

    if (start == end)
    {
        for (int j = 0; j < end; j++)
        {
            cout << a[j] << " ";
        }
        cout << endl;
    }
    for (int i = start; i < end; i++)
    {
        swap(a[start], a[i]);

        Perm(start + 1, end, a);

        swap(a[i], a[start]);
    }
}

        这是用递归法求全排列的一种方法,参考了这位大哥的方法:          https://blog.csdn.net/hf19931101/article/details/79452799

        其中start = 0,end就是行列式的阶数,也就是n。具体的解析可以看上面链接的。 

5.计算行列式每个项的值

        行列式最终的值是由几个项相加而成的,而那几个项则是由n个行列式中的元素相乘而得来的,而项中每项元素的列(行)下标则是1 2 3 ... n的某一种排列,而所有的项的列(行)下标就构成了1 2 3 ... n 的所有排列情况。

int Answer(int arr[u][u], int a[], int n, int t)              //计算行列式的每项的值
{
    int answer = 0;
    int temp_answer = 1;
    int t_2 = 0;

    for (int i = 0; i < n; i++)
    {
        temp_answer = temp_answer * arr[i][a[i]-1];
    }

    t_2 = pow(-1, t);

    answer = temp_answer * t_2;

    return answer;
}

        t 就是该项的各个元素的列(行)下标所对应的逆序数。temp_answer是该项中元素的累乘。t_2则是 - 1 的t次方。

6.所有项相加得出最终结果

        我们定义一个Final_Answer来作为最终结果,并且将Answer函数和Perm函数以及Reverse相融合。

void Perm(int start, int end, int a[], int arr[10][10], int &Final_Answer)                
{

    if (start == end)
    {
        Final_Answer = Final_Answer + Answer(arr, a, end, Reverse(end, a));
        return;
    }
    for (int i = start; i < end; i++)
    {
        swap(a[start], a[i]);      
        Perm(start + 1, end, a, arr, Final_Answer);  
        swap(a[i], a[start]);      
    }

}

        Final_Answer的值是一个值传递,因此我们用&来进行引用(或者利用指针)。Reverse函数所在的位置就是Answer函数的 t ,也就是逆序数。最后再在main函数之中调用并cout一下即可。

    Perm(0, n, a, arr, Final_Answer);

    cout << "行列式的值为: " << Final_Answer << endl;

7.全部代码

#include <iostream>
#include <cmath>
using namespace std;


int Reverse(int n, int a[])                 
{
    int t = 0;
    for (int i = 1; i < n; i++)
    {
        for (int h = 0; h < i; h++)
        {
            if (a[i]<a[h])
            {
                t = t + 1;
            }
        }
    }

    return t;
}

int Answer(int arr[10][10], int a[], int n, int t)              
{
    int answer = 0;
    int temp_answer = 1;
    int t_2 = 0;

    for (int i = 0; i < n; i++)
    {
        temp_answer = temp_answer * arr[i][a[i]-1];
    }

    t_2 = pow(-1, t);

    answer = temp_answer * t_2;

    return answer;
}

void Perm(int start, int end, int a[], int arr[10][10], int &Final_Answer)                
{

    if (start == end)
    {
        Final_Answer = Final_Answer + Answer(arr, a, end, Reverse(end, a));
        return;
    }
    for (int i = start; i < end; i++)
    {
        swap(a[start], a[i]);      
        Perm(start + 1, end, a, arr, Final_Answer);   
        swap(a[i], a[start]);      
    }

}


int main() 
{
    int Final_Answer = 0;
    int i, n, a[10];
    int arr[10][10];
    cout << "请输入行列式的阶数" << endl;
    cin >> n;
    for (i = 0; i < n; i++)         //给排列赋值
    {
        a[i] = i + 1;
    }

    for (int i = 0; i < n; i++)
    {
        cout << endl;
        for (int h = 0; h < n; h++)
        {
            cout << "a" << i + 1 << h + 1 << " 的值:";
            cin >> arr[i][h];
        }
    }

    Perm(0, n, a, arr, Final_Answer);

    cout << "行列式的值为: " << Final_Answer << endl;

    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值