温馨提示:本文翻译自stackoverflow.com,查看原文请点击:c - determinant program not working correctly
c pointers recursion

c - 行列式程序无法正常运行

发布于 2020-04-03 23:56:58

我写了一个程序,使用递归(拉普拉斯定理)来找到一个乘n矩阵的行列式。

它们是三个功能

1)determinant()查找n * n矩阵的行列式

2)create()动态分配一个* n数组

3)copy()创建n * n数组的n-1 * n-1个未成年人

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int determinant(int **a,int size,int noentry);// find determinant using recursion
int copy(int **b,int **a,int size,int noentry);//copy elements to minor
int **create(int size); // dynamically allocate a two dimensional array
 int main()
{
 int **a,size,i,j,y;
 printf("enter the order of the determinant \n");
 scanf("%d",&size);
 a=create(size);
 printf("enter your elements \n");
 for(i=0;i<size;i++)
{
    for(j=0;j<size;j++)
    {
        scanf("%d",&a[i][j]);
    }
 }
y=determinant(a,size,0);
printf("the determinant is %d \n",y);
 return 0;
}
int  determinant(int **a,int size,int noentry)
{
int i;
static int det=0;
if(size<=2)
    return a[0][0]*a[1][1]-a[0][1]*a[1][0];
else
{
    for(i=0;i<size;i++)
    {

        int **b;
        b=create(size-1);
        copy(b,a,size-1,i);
        det= det+pow(-1,i)*a[0][i]*determinant(b,size-1,i);
    }
    return det;
 }
}
int copy(int **b,int **a,int size,int noentry)
{
 int i,j,k;
 for(i=1;i<=size;i++)
{
    k=0;
    for(j=0;j<=size;j++)
    {
        if(j==noentry)
            continue;
        else
        {
            b[i-1][k]=a[i][j];
            k++;
        }
    }
}
return size;
}
int **create(int size)
{
 int **b;
 if(size<=0)
 {
    printf("the size cannot be negative/null \n");
    return NULL;
}
int i;
printf("entered the create function \n");
b=(int **)malloc(sizeof(int *)*size);
for(i=0;i<size;i++)
    b[i]=(int *)malloc(size*sizeof(int));
return b;
}

该程序对于3 x 3矩阵正常工作,但对于4 x 4矩阵却没有,我无法发现错误。

查看更多

提问者
kapil
被浏览
40
Serge Ballesta 2015-12-04 21:33

首先,您永远不会释放分配的块,这是不好的。您应该创建一种destroy方法来释放先前分配的矩阵,并在每次create调用时调用一次

接下来,将未使用的noentry参数传递determinant应该是:int determinant(int **a,int size);

但是,导致错误的原因是determinant方法中的det变量是静态的。当您递归时determinant,每个新调用应具有自己的det副本,或共享相同副本。

TL / DR:只需删除函数中变量static限定符即可detdeterminant

最后建议:如果您分配矩阵,则调试会更容易...矩阵明智!

int **create(int size)
{
    int i;
    int **b;
    if(size<=0)
    {
        printf("the size cannot be negative/null \n");
        return NULL;
    }
    printf("entered the create function \n");
    b=(int **)malloc(sizeof(int *)*size);
    b[0]=(int *)malloc(size * size*sizeof(int));
    for(i=1;i<size;i++)
        b[i]=b[0] + i * size;
    return b;
}
void destroy(int **a) {
    free(a[0]);
    free(a);
}

这样,整个矩阵就可以使用连续的内存,通过观察以开头的size²整数,轻松地在调试器中查看其内容a[0]作为副作用,破坏功能非常简单。

只是穷举,固定determinant函数变为:

int  determinant(int **a,int size)
{
    int i;
    int det=0;
    int m1 = 1;
    if(size<=2)
        return a[0][0]*a[1][1]-a[0][1]*a[1][0];
    else
    {
        for(i=0;i<size;i++)
        {

            int **b;
            b=create(size-1);
            copy(b,a,size-1,i);
            det= det+m1*a[0][i]*determinant(b,size-1);
            destroy(b);
            m1 = - m1;
        }
        return det;
    }
}