【问题标题】:(C++) Function to calc Determinant of a dynamic matrix(C++) 计算动态矩阵行列式的函数
【发布时间】:2020-01-29 22:21:45
【问题描述】:

我目前正在开发一个程序,该程序应该向用户询问一些数据并根据它们创建 2 个矩阵。稍后程序还应该可以选择计算这些矩阵的行列式。 我想在函数(int 行列式)中完成此操作,但是当我尝试将其用于矩阵 3x3 或更大时,程序会出现错误(进程返回 -1073741819(0xC0000005)执行时间:23.503 秒)

可能是什么原因造成的?

#include <iostream>
#include <windows.h>
#include <cstdlib>
#include <time.h>
#include <stdio.h>
#include <conio.h>
#include <math.h>

using namespace std;

void inputdata (int&,int&,int&,int&,int&,int&);
void printmatrix (int**,int&,int&);
int determinant(int**, int);
bool ifmatsquare (int, int);

int main()
{
    int rows1=0,rows2=0,colm1=0,colm2=0,matmin=0,matmax=0;
    char menuoption;


    while (true){

    inputdata(rows1,rows2,colm1,colm2,matmin,matmax);

    system("cls");


    int **matrix1(0);
    int **matrix2(0);

    matrix1 = new int *[rows1];
    matrix2 = new int *[rows2];

   srand(time(NULL));

    for(int  i = 0; i <rows1; i++){
        matrix1[i] = new int[colm1];
        for(int j = 0; j <colm1; j++){
            matrix1[i][j] = rand()%(matmax-matmin+1) + matmin;;
        }
    }


    for(int i = 0; i <rows2; i++){
        matrix2[i] = new int[colm2];
        for(int j = 0; j <colm2; j++){
            matrix2[i][j] = rand()%(matmax-matmin+1) + matmin;;
        }
    }

    for (bool menu=true; menu==true;){

    printmatrix(matrix1, rows1, colm1);
    cout<< endl;
    printmatrix(matrix2, rows2, colm2);
    cout<< endl;
    cout<< endl;

    cout<< "MENU \n" <<endl;
    cout<< "1: XXX" <<endl;
    cout<< "2: XXX" <<endl;
    cout<< "3: Calculate Determinant" <<endl;
    cout<< "4: XXX" <<endl;
    cout<< "5: Reset program" <<endl;
    cout<< "6: Exit program" <<endl;
    cout<< endl;

    menuoption = getch();

    switch(menuoption){
    /*case '1':
        //jakis kod
        break;
    */
    case '3':
        char mat1or2;
        cout<< "Matrix 1 or 2: ";
        do {
        mat1or2 = getch();
        } while ((mat1or2!='1') && (mat1or2!='2'));

        if ((mat1or2=='1')&&(ifmatsquare(rows1,colm1)==true))
        cout<<"\nDeterminant for matrix 1 is "<<determinant(matrix1, rows1)<<endl;
        else if ((mat1or2=='2')&&(ifmatsquare(rows2,colm2)==true)){
        cout<<"\nDeterminant for matrix 2 is "<<determinant(matrix2, rows2)<<endl;
        }

        cout<< "Press any key to return to menu";
        getch();
        break;

    case '5':
        menu=false;
        break;

    case '6':
        delete []matrix1;
        delete []matrix2;
        exit(0);
        break;

    default:
        cout<< "No such option, press any key to reurn to menu!"<<endl;
        getch();
        break;
    }

    system("cls");
}

    delete []matrix1;
    delete []matrix2;

}

    return 0;
}

void inputdata (int &r1,int &r2,int &c1,int &c2,int &mmin, int &mmax){
    cout << "Give number of rows for matrix 1" << endl;
    cin >> r1;

    cout << "Give number of columns for matrix 1" << endl;
    cin >> c1;

    do{
        cout << "Give number of rows for matrix 2 (should be the same as columns for matrix 1)" << endl;
        cin >> r2;
        } while(r2!=c1);

    cout << "Give number of columns for matrix 2" << endl;
    cin >> c2;

    cout << "Give MIN value for matrix" << endl;
    cin >> mmin;

    do{
        cout << "Give MAX value for matrix" << endl;
        cin >> mmax;
    } while(mmax<mmin);
}

void printmatrix(int **a, int &rows, int &colm){
        for (int x = 0; x < rows; x++)
        {
            for (int y = 0; y < colm; y++)
            {
                printf("%4d", a[x][y]);
            }
            printf("\n");
        }
    }

bool ifmatsquare(int row, int col){

    if (row == col){
        cout<<endl;
        return true;}
    else
        cout<<"Determinant can be caclucated only for square matrix"<<endl;
        return false;
}

int determinant(int **a, int size) {
    int det = 0;
    int **submatrix(0);
    if (size == 2)
        return ((a[0][0] * a[1][1]) - (a[1][0] * a[0][1]));
    else {
        for (int x = 0; x < size; x++) {
            int subi = 0;
            for (int i = 1; i < size; i++) {
                int subj = 0;
                for (int j = 0; j < size; j++) {
                    if (j == x)
                    continue;
                    submatrix[subi][subj] = a[i][j];
                    subj++;
                    }
                subi++;
            }
            det = det + (pow(-1, x) * a[0][x] * determinant(submatrix, size - 1));
        }
    }
    return det;
}

【问题讨论】:

  • 旁注:pow(-1, x) 是一种非常重量级的方法,用于翻转符号位以获得偶数和赔率,除非编译器识别出您在做什么并替换它。 pow 旨在计算非常讨厌的 ,例如 pi 的 e 次方。测试最后一点(任何体面的编译器都会优化 x%2)并返回 1 或 -1 会更快更干净。
  • 在主题上,您遇到了访问冲突(错误 0xC0000005),因此您的程序可能超出了有效内存。确保没有数组访问会破坏数组,并且由于determinant 是递归的,请确保递归在您认为应该结束的地方结束。使用您的开发环境的调试器来帮助跟踪递归,如果您利用第一条评论中提出的更智能的矩阵,std::vector::at 方法可以帮助捕获缓冲区违规。
  • 内存未为submatrix 中的determinant 保留
  • @Damien - 你能建议在哪里以及如何做吗?我目前正在尝试调试它(使用 cout

标签: c++ function matrix


【解决方案1】:

感谢您的帮助。

你是对的,我没有为子矩阵声明空间

我修改了我的函数,它现在如下所示(并且按预期工作)

int determinant(int **a, int matsize) {
int det = 0;
int** submatrix = new int*[matsize];
for (int i = 0; i < matsize; ++i)
submatrix[i] = new int[matsize];

if (matsize == 1)
    return a[0][0];
else if (matsize == 2)
    return ((a[0][0] * a[1][1]) - (a[1][0] * a[0][1]));
else {
    for (int x = 0; x < matsize; x++) {
    int subi = 0;
    for (int i = 1; i < matsize; i++) {
    int subj = 0;
    for (int j = 0; j < matsize; j++) {
    if (j == x)
    continue;
    submatrix[subi][subj] = a[i][j];
    subj++;
    }
    subi++;
    }
    det = det + (pow(-1, x) * a[0][x] * determinant(submatrix, matsize - 1));
    }
    }

    for (int i = 0; i < matsize; ++i)
    delete [] submatrix[i];
    delete [] submatrix;

    return det;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-12
    • 1970-01-01
    • 2011-02-24
    • 1970-01-01
    • 1970-01-01
    • 2014-02-08
    • 2018-11-09
    • 2019-03-25
    相关资源
    最近更新 更多