【问题标题】:Determinant of matrix with recursion递归矩阵的行列式
【发布时间】:2018-03-14 16:15:32
【问题描述】:

下面的代码递归地计算q阶矩阵的行列式。它适用于 q=3 和 q=2 但对于 q=4 它输出垃圾值,每次运行程序时都会改变: 这里出了什么问题?

#include <stdio.h>
#include <math.h>

int det(int q, int arr[q][q]);
int main(void)
{
    int arr[4][4] = {
            {2,4,9,8},
            {6,3,4,5},
            {5,7,8,6},
            {3,2,5,7}
            };
    printf("value of determinant is %d\n", det(4, arr));
}

int det(int q, int arr[q][q])
{   
    if(q>2)
    {
    int i, j, k, m, n, s[q-1][q-1], d=0, cof;
    for(k=-1,i=0,j=0;k<q-1;k++)
    {
        i=0;j=0;
        for(m=1;m<q;m++,i++)
        {
            n=0;j=0;
            for(n,j;n<k+1;n++,j++)
            {
                s[i][j] = arr[m][n];
            }
            n=q-1+k;
            for(n;n<q;n++,j++)
            {
                s[i][j] = (arr[m][n]);
            }
        }
        cof = (arr[0][k+1])*(pow(-1,k+1));
        d += cof*det(q-1, s);
    }
    return d;
    }
    else if(q==2)
    {
        int d = ((arr[0][0])*(arr[1][1])-(arr[0][1])*(arr[1][0]));      
        return d;
    }
}

【问题讨论】:

  • 你使用调试器吗?您是否尝试过使用断点单步执行?问题到底出在哪里?
  • 你有没有尝试过basic调试。
  • 你为什么要使用递归呢?代码效率太高,可读性太强?为什么你用一个字母给你所有的变量命名?
  • @Lundin:递归是我想到的第一件事,因为当我们取行列式时,我们基本上求和(辅因子*另一个行列式),所以它本质上就像再次调用函数。有没有更好的办法?
  • 我对递归没有任何特别的反对——这是构造这个算法的一种自然方式。但是由于(至少)许多无意义的变量名称、空格使用不足、括号使用过多以及变量范围不必要的宽泛,呈现的代码难以阅读。

标签: c arrays recursion determinants


【解决方案1】:

在您的代码中,问题的主要根源是算法。建议您刷新行列式概念。您可以查看下面的代码以检查您使用的算法中的错误。

#include <stdio.h>
#include <math.h>

int det(int q, int arr[q][q]);
int main(void)
{
    int arr[5][5] = {
            {2,4,9,1,2},
            {6,3,4,2,6},
            {5,7,8,6,9},
            {9,1,5,3,3},
            {3,2,5,3,9}
            };
    printf("value of determinant is %d\n", det(5, arr));
    return 0;
}

int det(int q, int arr[q][q])
{
    if(q>2)
    {
        int resultOfSubStep = 0 ; //Final result that will be returned
        int smallerMatrix[q-1][q-1] ; //Matrix in which smaller matrix are to be stored which will be given as arguments to det function in current recursion 
        int i = 0 ; 
        for(;i<q;i++){
            int j = 0 ;

            for (;j<q-1;j++) { //This for loop copies the element required from arr into smallerMatrix
                int counter = 0 ;
                int k = 0 ;
                for (;k<q;k++){
                    if(k == i)continue;
                    smallerMatrix[j][counter] = arr[j+1][k];
                    counter++;
                }
            }
            int k1 = arr[0][i]*det(q-1, smallerMatrix); //This is the result of determinant of q-1*q-1 matrix
            resultOfSubStep += pow(-1,i)*k1; //multiplied by -1 or +1 according to the position of root element
        }
        return resultOfSubStep;
    }
    else if(q==2)
    {
        int d = ((arr[0][0])*(arr[1][1])-(arr[0][1])*(arr[1][0]));
        return d;
    }
    else return arr[0][0];
}

在 cmets 部分,您询问了其他方法。在我看来,LU 分解是最简单的一种。你可以在LU Decomposition上查看它的详细信息。在这种方法中,你必须将给定的矩阵减少为上三角矩阵或下三角矩阵,然后只取对角元素的乘积。所以不需要递归。 希望这会有所帮助。

【讨论】:

  • Minor: else return -1 ; --> return -1 ; 捕获所有病理病例,包括q &lt; 0。在之前的q 测试中也不需要else。
  • @chux 我根据您的建议修改了答案。可以吗?请告知是否需要进一步修改。谢谢。
猜你喜欢
  • 2015-05-25
  • 1970-01-01
  • 1970-01-01
  • 2019-03-25
  • 2016-10-14
  • 2018-11-27
  • 1970-01-01
  • 2021-09-20
  • 2020-03-11
相关资源
最近更新 更多