行列式的计算

版本一:

/*********************************************
思路:
对行列式进行初等变换,将某一列化至只有一个非零数
交换完毕之后产生新的数组和维度,递归执行determinant,当维度为2时,
计算该行列式的值,返回这个值
回溯返回最终结果
*********************************************/

#include<stdio.h>
#include<string.h>

int a[100][100];
int divisor = 1;
int determinant(int dimension);
void exchange(int row, int dimension);
int main()
{
    int n = 0;
    memset(a, 0, sizeof(a));
    printf("Please enter the dimension of the determinant:\n");
    scanf("%d", &n);
    printf("Please enter the determinant:\n");
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<n; j++)
        {
            scanf("%d", &a[i][j]);
        }
    }
    int result = determinant(n);
    printf("result=%d", result);
    result /= divisor;
    printf("divisor=%d", divisor);
    printf("The result of this determinant is %d\n", result);
    return 0;
}
/*********************************************
此处初等变换的思路就是:
总以最后一行为标准值,然后让待交换的行的每一列的
值与标准行的最后一列的值相乘,
将最后的结果除以该值
再将标准行的每一列的值乘以待交换行的最后一列的值,
将最后的结果除以该值
最后将待处理的行的每一列的值减去标准行调整之后的值
这样就可以将待处理行的最后一列的值调整为0
*********************************************/

/*********************************************
为了避免出现最后一行为0的情况,我们先把所有行都加到最后一行上
此外,对于最后一列为0的行,我们无须进行初等变换处理
*********************************************/
int determinant(int dimension)
{

    for(int i=dimension-2; i>=0; i--)
    {
        if(a[i][dimension-1] == 0)
            continue;
        for(int j=0; j<dimension; j++)
        {
            a[dimension-1][j] += a[i][j];
        }
    }
    int result;
    if(dimension == 2)
    {
        result = a[0][0]*a[1][1]-a[0][1]*a[1][0];
        return result;
    }

    //该for循环会把最后一列的值处理成只有最后一行的值为非零
    //在进行乘运算时,需要先把乘数保存起来,不然在计算时
    //其值会被改变,从而影响最终结果
    for(int i=dimension-2; i>=0; i--)
    {
        if(a[i][dimension-1] == 0)
            continue;
        int sign_1 = a[dimension-1][dimension-1];
        int sign_2 = a[i][dimension-1];
        for(int j=0; j<dimension; j++)
        {
            a[i][j] *= sign_1;
            a[dimension-1][j] *= sign_2;
        }
        divisor *= sign_1;
        divisor *= sign_2;
        exchange(i, dimension);
    }
    int product = a[dimension-1][dimension-1];
    //由于我们选取的总是最后一行的最后一列,故而代数余子式的系数总是为+1
    //直接相乘即可
    result = product*determinant(dimension-1);
    return result;
}

void exchange(int row, int dimension)
{
    for(int i=0; i<dimension; i++)
    {
        a[row][i] -= a[dimension-1][i];
    }
}

算法太笨拙,维度或者值稍微大一点的行列式都无法计算

在参考网上的文章之后,我改变了思路,直接按照行列式的按行按列展开来进行计算,公式如下:
这里写图片描述

测试代码,可将加过输出到文件查看中间结果:

#include<stdio.h>
#include<string.h>

int a[100][100];
int determinant(int a[][100], int dimension);
void spread(int a[][100], int row, int dimension);
void copy_m(int src[][100], int dst[][100], int dimension);
int main(int argc, char* argv[])
{
    int summ = 0;
    int n = 0;
    memset(a, 0, sizeof(a));
    //printf("Please enter the dimension of the determinant:\n");
    for(int k = strlen(argv[1])-1; k >= 0; k--)
    {
        int ttmp = 1;
        for(int j=0; j<strlen(argv[1])-1-k; j++)
            ttmp *= 10;
        summ += (argv[1][k]-'0')*ttmp;
    }
    n = summ;
    //printf("Please enter the determinant:\n");
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<n; j++)
        {
            summ = 0;
            int tmp = 0;
            if(argv[i*5+j+2][0] == '-')
            {
                tmp = 1;
            }
            for(int k = strlen(argv[i*5+j+2])-1; k >= tmp; k--)
            {
                int ttmp = 1;
                for(int jj=0; jj<strlen(argv[i*5+j+2])-1-k; jj++)
                    ttmp *= 10;
                summ += (argv[i*5+j+2][k]-'0')*ttmp;
               // printf("summ=%d\n", summ);
            }
            if(tmp)
                summ = 0-summ;
            a[i][j] = summ;
        }
    }

for(int i=0; i<n; i++)
{
    for(int j=0; j<n; j++)
        printf("%d ", a[i][j]);
    printf("\n");
}
printf("\n\n");

    printf("The result of this determinant is %d\n", determinant(a, n));
    return 0;
}

int determinant(int a[][100], int dimension)
{
for(int i=0; i<dimension; i++)
{
    for(int j=0; j<dimension; j++)
        printf("%d ", a[i][j]);
    printf("\n");
}
printf("\n\n");

    int sum= 0;
    //需要构造一个原矩阵的拷贝
    int m_copy[100][100];
    memset(m_copy, 0, sizeof(m_copy));
    copy_m(a, m_copy, dimension);
    if(dimension == 2)
    {
        int result = a[0][0]*a[1][1]-a[0][1]*a[1][0];
        return result;
    }
    for(int i=0; i<dimension; i++)
    {
        if(a[i][dimension-1]==0)
            continue;
        spread(a, i, dimension);



        int tmp = a[i][dimension-1]*determinant(a, dimension-1);
printf("tmp=%d\n", tmp);
        int sign = (i+1+dimension)%2==0?1:(-1);
        //sum出了问题
        sum += sign*tmp;
printf("sum=%d\n", sum);
        copy_m(m_copy, a, dimension);
    }
printf("\nreturn here!!\n\n");
    return sum;
}

//每次都展开最后一列
//这样可以省去向左缩进的处理
//如果选中了最后一行最后一列
//我们只需要return即可,因为我们不需要对其进行处理
//维度降低1的原数组就是处理后的数组
void spread(int a[][100], int row, int dimension)
{
    if(row == dimension-1)
        return;
    for(int i=row; i<dimension-1; i++)
        for(int j=0; j<dimension-1; j++)
            a[i][j] = a[i+1][j];
}

void copy_m(int src[][100], int dst[][100], int dimension)
{
    for(int i=0; i<dimension; i++)
        for(int j=0; j<dimension; j++)
            dst[i][j] = src[i][j];
}

最终代码:

/*+++++++++++++++++++
Author:     include_heqile
Date:       Thur May 31th 2018
School:     Hrbust University of Science and Technology
E-mail:     [email protected]
++++++++++++++++++++*/

#include<stdio.h>
#include<string.h>

int a[100][100];
int determinant(int a[][100], int dimension);
void spread(int a[][100], int row, int dimension);
void copy_m(int src[][100], int dst[][100], int dimension);
int main()
{
    int summ = 0;
    int n = 0;
    memset(a, 0, sizeof(a));
    printf("Please enter the dimension of the determinant:\n");
    scanf("%d", &n);
    printf("Please enter the determinant:\n");
    for(int i=0; i<n; i++)
        for(int j=0; j<n; j++)
            scanf("%d", &a[i][j]);
    printf("The result of this determinant is %d\n", determinant(a, n));
    return 0;
}

int determinant(int a[][100], int dimension)
{
    int sum= 0;
    int m_copy[100][100];
    memset(m_copy, 0, sizeof(m_copy));
    copy_m(a, m_copy, dimension);
    if(dimension == 2)
    {
        int result = a[0][0]*a[1][1]-a[0][1]*a[1][0];
        return result;
    }
    for(int i=0; i<dimension; i++)
    {
        if(a[i][dimension-1]==0)
            continue;
        spread(a, i, dimension);
        int tmp = a[i][dimension-1]*determinant(a, dimension-1);
        int sign = (i+1+dimension)%2==0?1:(-1);
        sum += sign*tmp;
        copy_m(m_copy, a, dimension);
    }
    return sum;
}

void spread(int a[][100], int row, int dimension)
{
    if(row == dimension-1)
        return;
    for(int i=row; i<dimension-1; i++)
        for(int j=0; j<dimension-1; j++)
            a[i][j] = a[i+1][j];
}

void copy_m(int src[][100], int dst[][100], int dimension)
{
    for(int i=0; i<dimension; i++)
        for(int j=0; j<dimension; j++)
            dst[i][j] = src[i][j];
}

猜你喜欢

转载自blog.csdn.net/include_heqile/article/details/80529193