我目前正在尝试编写一个程序来查找 NxN 矩阵的行列式,但我遇到了 N 大于 2 的递归问题。基本上据我所知,它没有这样做,它只是运行函数一旦使用我的调试选项显示该函数在列中运行但顺序永远不会下降,然后无论如何它都会为我的行列式提供零。我试着到处寻找关于我做错了什么的任何想法,但我似乎无法找到任何答案,我什至找到了与我做基本相同的事情的例子并且无论如何使用它们都会给我零,所以我很困惑 :(。如果有人能快速浏览我的代码并告诉我我在哪里是个白痴,我将不胜感激!(对格式感到抱歉,它在我的编辑器中看起来不错,但我似乎无法掌握它在这里)
代码:
#include<stdlib.h>
#include<stdio.h>
#include<math.h>
double det(double **mat, int order);
int main (int argc, char* argv[])
{
FILE* input;
int row,column,N;
double **matrix;
N=3;
matrix=(double**)malloc(N*sizeof(double));
input=fopen("matrix.dat", "r");
if(input !=(FILE*) NULL)
{
for(row=0; row<N; row++)
{
matrix[row]=(double*)malloc(N*sizeof(double));
}
for(row=0; row<N; row++)
{
printf("| ");
for(column=0; column<N; column++)
{
fscanf(input,"%lf ", &matrix[row][column]);
printf("%g ", matrix[row][column]);
}
if(row != (N/2))
{
printf("|\n");
}
else
{
printf("|= %lf \n", det(matrix, N) );
}
}
return(EXIT_SUCCESS);
}
else
{
printf("*********************ERROR*********************\n");
printf("** Cannot open input file 'matrix.dat' make **\n");
printf("** sure file is present in working directory **\n");
printf("***********************************************\n");
return(EXIT_FAILURE);
}
}
double det(double **mat, int order)
{
int debug;
double cofact[order], determinant, **temp;
determinant = 0;
debug=0;
if(order==1)
{
determinant=mat[0][0];
if(debug==1)
{
printf("order 1 if\n");
}
}
else if(order==2)
{
determinant= ((mat[0][0]*mat[1][1])-(mat[0][1]*mat[1][0]));
if(debug==1)
{
printf("order 2 if\n");
}
}
else
{
int column, rowtemp, coltemp, colread;
for (column=0; column<order; column++)
{
/* Now create an array of size N-1 to store temporary data used for calculating minors */
temp= malloc((order-1)*sizeof(*temp));
for(rowtemp=0; rowtemp<(order-1); rowtemp++)
{
/* Now asign each element in the array temp as an array of size N-1 itself */
temp[rowtemp]=malloc((order-1)*sizeof(double));
}
for(rowtemp=1; rowtemp<order; rowtemp++)
{
/* We now have our empty array, and will now fill it by assinging row and collumn values from the original mat with the aprroriate elements excluded */
coltemp=0;
for(colread=0; colread<order; colread++)
{
/* When the collumn of temp is equal to the collumn of the matrix, this indicates this row should be exlcuded and is skiped over */
if(colread==column)
{
continue;
}
temp[rowtemp-1][coltemp] = mat[rowtemp][colread];
coltemp++;
}
}
if(debug==1)
{
printf("column =%d, order=%d\n", column, order);
}
determinant+=(mat[0][column]*(1 - 2*(column & 1))*det(temp, order-1));
}
}
return(determinant);
}
最佳答案
temp= (double **)malloc((order-1)*sizeof(double));
只要sizeof(double*) <= sizeof(double)
就不会导致崩溃,在通常的 32 位或 64 位系统上就是这种情况,但它在概念上是错误的。您正在为 double*
的数组分配空间, 所以因子应该是 sizeof(double*)
或者,更好,因为它在类型更改时是不变的,sizeof *temp
,
temp = malloc((order-1) * sizeof *temp);
(而且您不需要在 C 中转换 malloc
的结果,最好不要这样做,因为转换可能会隐藏错误,例如忘记 #include <stdlib.h>
。)
分配也是如此
matrix=(double**)malloc(N*sizeof(double));
在main
.
在行列式的计算中,
for(coltemp=0; coltemp<order; coltemp++)
{
for(colread=0; colread<order; colread++)
{
/* When the collumn of temp is equal to the collumn of the matrix, this indicates this row should be exlcuded and is skiped over */
if(colread==column)
{
continue;
}
temp[rowtemp-1][coltemp] = mat[rowtemp][colread];
coltemp++;
}
}
您在列中循环两次,一次是针对 coltemp == 0
,然后在内循环中,coltemp
递增 order-1
次,因此内部循环第二次运行 coltemp == order-1
在开始时。然后 coltemp
在循环中再次递增多次,并且您正在超出分配内存的范围。
应该删除外循环,coltemp = 0;
内循环就是您所需要的。
pow(-1,column))
不是确定符号的好方法。
(1 - 2*(column & 1))
比调用 pow
更快.
最后,在 main
for(row=0; row<N; row++)
{
printf("| ");
for(column=0; column<N; column++)
{
fscanf(input,"%lf ", &matrix[row][column]);
printf("%g ", matrix[row][column]);
}
if(row != (N/2))
{
printf("|\n");
}
else
{
printf("|= %lf \n", det(matrix, N) );
}
}
您正在打印 N/2
行的行列式,看起来不错,但那时您还没有扫描整个矩阵,所以行 N/2 + 1
至 N-1
包含未初始化的数据,这些数据不太可能全为零。如果您更改 if (row != N/2)
至 if (row != N-1)
,它会工作,但是,处理它的正确方法是将矩阵的扫描与计算和打印分开。这些都是独立的操作,应该在它们自己的单独函数中处理。
关于c - NxN矩阵行列式递归问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13429832/