我目前正试图编写一个程序,以找到一个NxN矩阵的行列式,但我有一个问题的递归N大于2。基本上,根据我的判断,它并没有这样做,它只是运行函数一次,因为使用我的debug选项显示,函数在列中运行,但顺序永远不会下降,然后它给我的行列式零,不管怎样。我试着到处寻找我做错了什么,但我似乎找不到任何答案,我甚至找到了一些和我做的事情基本相同的例子,不管怎样,使用它们都会给我零分,所以我很困惑:(。如果有人能快速浏览一下我的代码,告诉我我在哪里是个白痴,我会非常感激!(很抱歉,在我的编辑看来,格式没问题,但我似乎无法理解它的含义)
代码:

#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 + 1N-1行包含未初始化的数据,这些数据不太可能全部为零。如果将if (row != N/2)更改为if (row != N-1),它将起作用,但是,正确的处理方法是将矩阵扫描与计算和打印分离开来。这些都是独立的操作,应该在它们各自的函数中处理。

关于c - NxN矩阵行列式递归问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13429832/

10-12 19:22