n n n矩阵行列式的代码

时间:2017-03-15 06:07:45

标签: c algorithm matrix

我编写了我的代码并尝试在Codeblocks中编译,但它无法正常工作。在运行编程时,它在“int det(,)”中显示错误。我也尝试使用“* a”,但它没有用。它只是问我矩阵的大小和值然后停止。我正在编写完整的程序,但我认为该错误属于int det(int n, int a[][])

#include<math.h>

main()

{

    int n,i,j;

    printf("enter the size of the matrix");

    scanf("%d", &n);


    int a[n][n];

    printf("enter the matrix \n");

    for (i=0; i<n; i++)
    {
        for(j=0; j<n; j++)

            {
                printf(" \n");

                scanf("%d",  &a[i][j]);
            }

    }

    printf("%d determinant is", det(a,n));

}

int det( int a[][n],int n)

{

    int i, j,k,d,l=0 ;

    if(n=2)

        {
            d = a[0][0]*a[1][1] - a[0][1]*a[1][0];

            return (d);

        }

    else

        for ( k = 0; k < n ; k++ )

        {
            int b[n-1][n-1];
            for (i=1; i<n; i++)

            {

                for(j=0 && j!=k ; j<n; j++)
                {
                    b[i][j]=a[i][j];
                }

            }

            l = a[0][j]*pow(-1,j)*det(b,n-1)+l;

        }

    return(l);

}

更新

更新的代码:

    #include<math.h>
#include<stdio.h>
int det( int n, int a[][n]);


int main(void)

{

    int n,i,j;

    printf("enter the size of the matrix ");

    scanf("%d", &n);

    int a[n][n];

    printf("enter the matrix \n");

    for (i=0; i<n; i++)
    {
        for(j=0; j<n; j++)

            {
                printf(" ");

                scanf("%d",  &a[i][j]);
            }
      //  printf("\n");
    }

    printf(" determinant is %d\n", det(n,a));

}

int det( int n, int a[][n])

{

    int i, aj,bj,k,d,p=0 ;
    int sign =1;
    if(n==2)

        {
            d = a[0][0]*a[1][1] - a[0][1]*a[1][0];

            return d;

        }

    else

        for ( k = 0; k < n ; k++ )

        {
            int b[n-1][n-1];
            for (i=1; i<n; i++)

            {

                for(aj=0,bj=0 ; aj<n; aj++)
                {
                    if(aj==k) continue;
                    b[i-1][bj]=a[i][aj];
                    ++bj;
                }

            }

            p = a[0][aj]*pow(-1,k)*det(n-1, b)+p;
        }

    return p;

}

[Spektre编辑]

上次计算中的索引错误。我会将您的det代码更改为(我的评论摘要):

int det( int n, int a[][n])
    {   
    if(n<=0) return 0;                                 // stop recursion
    if(n==1) return a[0][0];                           // stop recursion
    if(n==2) return a[0][0]*a[1][1] - a[0][1]*a[1][0]; // stop recursion
    int i,aj,bj,k,p,sign,b[n-1][n-1];
    for (p=0,  sign=+1, k = 0; k < n ; k++, sign=-sign)
        {
        for (i=1; i<n; i++)
            {
            for (aj=0,bj=0 ; aj<n; aj++)
             if (aj!=k) 
                {
                b[i-1][bj]=a[i][aj];
                ++bj;
                }
            }
        p= p + (sign*a[0][k]*det(n-1, b)); // here you had aj instead of k causing problems !!!
        }
    return p;
    }

遗憾的是我的编译器不允许这种类型的数组传递,我需要将它更改为模板或动态数组,这会让你感到困惑......所以我测试了这个,看起来很有效:

const int N=3;
int A[N][N]=
    {
    { 1,2,3 },
    { 2,3,1 },
    { 3,1,2 },
    };
int det(const int n, int a[][n])
    {
    if(n<=0) return 0;                                 // stop recursion
    if(n==1) return a[0][0];                           // stop recursion
    if(n==2) return a[0][0]*a[1][1] - a[0][1]*a[1][0]; // stop recursion
    int i,aj,bj,k,p,sign,b[N][N];
    for (i=0;i<n;i++) for (k=0;k<n;k++) b[i][k]=0;
    for (p=0, sign=+1, k = 0; k < n ; k++, sign=-sign)
        {
        for (i=1; i<n; i++)
            {
            for (aj=0,bj=0 ; aj<n; aj++)
             if (aj!=k)
                {
                b[i-1][bj]=a[i][aj];
                ++bj;
                }
            }
        p+= sign*a[0][k]*det(n-1,b); // here you had aj instead of k causing problems !!!
        }
    return p;
    }

结果det(N,A)=-18与我自己的决定函数匹配。

1 个答案:

答案 0 :(得分:2)

det()之前需要main()的函数原型,而size参数需要在函数调用中的VLA之前。此外,您应该将size_t用于数组索引而不是int

没有理由使用pow()替换标志;当需要交替使用符号时,请使用int sign = 1;并乘以-1

det()中的循环中,您有:

for(j=0 && j!=k ; j<n; j++) {}

意图跳过k列;相反,你需要写这个:

for (j = 0; j < n; j++) {
    if (j == k) continue;
    ...
}

但是这里还有一个问题:

b[i][j]=a[i][j];

由于b[][]a[][]的索引不相同,实际上b小于a,因此会导致写出越界{ {1}}。相反,您可以为两个矩阵声明单独的列索引:

b

最后,您将size_t aj, bj; ... for (aj = 0, bj = 0; aj < n; aj++) { if (aj == k) continue; b[i-1][bj] = a[i][aj]; ++bj; } ... } 的行列式乘以b的错误元素:

a

进行其他更正后,应该是:

l = a[0][j]*pow(-1,j)*det(b,n-1)+l;

以下是完整的修改代码:

l = sign * a[0][k] * det(n-1, b) + l;

以下是几个示例交互:

#include <stdio.h>

int det(size_t n, int a[n][n]);

int main(void)
{
    size_t n,i,j;

    printf("enter the size of the matrix: ");
    scanf("%zu", &n);

    int a[n][n];

    printf("enter the matrix: \n");
    for (i = 0; i < n; i++)
    {
        for(j = 0; j < n; j++)
        {
            scanf("%d",  &a[i][j]);
        }
    }

    printf("determinant is %d\n", det(n, a));

    return 0;
}

int det(size_t n, int a[][n])
{
    size_t i, aj, bj, k, d;
    int l = 0;
    int sign = 1;

    if(n == 2)
    {
        d = a[0][0] * a[1][1] - a[0][1] * a[1][0];

        return d;
    }

    else
        for (k = 0; k < n ; k++)
        {
            int b[n-1][n-1];

            for (i = 1; i < n; i++)
            {
                for (aj = 0, bj = 0; aj < n; aj++)
                {
                    if (aj == k) continue;
                    b[i-1][bj] = a[i][aj];
                    ++bj;
                }
            }

            l += sign * a[0][k] * det(n-1, b);
            sign *= -1;
        }

    return l;
}

更新

OP已发布更新的代码,此更新旨在解决新问题。首先,λ> ./a.out enter the size of the matrix: 3 enter the matrix: 1 2 3 4 5 6 7 8 9 determinant is 0 λ> ./a.out enter the size of the matrix: 3 enter the matrix: 1 -2 3 4 -5 6 7 8 -9 determinant is 42 必须(大部分)具有两个函数签名之一:

main()

int main(void);

现在,您必须在int main(int argc, char *argv[]); // equivalently int main(int argc, char **argv); 之前移动det()的定义,或添加函数原型:

main()

由于int det( int n, int a[][n]); 使用VLA,因此size参数必须位于数组参数之前,因此函数调用必须更改为:

det()

printf("%d determinant is", det(n, a));

最后,在p = a[0][k]*pow(-1,k)*det(n-1, b)+p; 的内部循环中,您必须保留两个索引,det()aj,因为bja[][]的大小不同, b[][]a[][]的元素并不完全一致:

b[][]

出于多种原因,我建议使用for(aj=0, bj=0 ; aj<n; aj++) { if(aj==k) continue; b[i-1][bj]=a[i][aj]; ++bj; } 进行符号替换;它涉及不必要的库调用,pow()的返回值为pow()

这些观点大部分都是在原始答案中提出的。进行这些更改后,您的代码对我有用。