我编写了我的代码并尝试在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
与我自己的决定函数匹配。
答案 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;
}
λ> ./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
,因为bj
和a[][]
的大小不同, 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()
。
这些观点大部分都是在原始答案中提出的。进行这些更改后,您的代码对我有用。