求解矩阵的行列式(c++描述)
新学期开始,学习了有关C++面向对象编程的内容,实现一个矩阵类,练练手,顺便复习一下上学期有关递归和线性代数方面的知识.
下面是一个矩阵类的头文件
class Matrix
{
public:
Matrix();
Matrix(const Matrix& m)//拷贝构造函数
Matrix(double *p, int r, int c)//构造函数,形参分别为用一维数组存储的矩阵以及它的行和列
~Matrix();//涉及动态内存分配需要自定义析构函数;
void print_mat();//打印整个矩阵
int get_row();
int get_col();
double* get_mat();
private:
int row;
int col;
double *mat;
}
求解矩阵的行列式一般有两种方法:
第一种主要的思想是通过矩阵变化将所求的矩阵化成三角矩阵,再求解三角矩阵的行列式(对角线上的元素的乘积);
第二种方法是利用余因子展开的方法来求解
detA=a11detA11−a12detA12+....(−1)1+na1ndetA1n=∑nj=1(−1)1+na1jdetA1j
显然第二种方法可以在计算机中用递归来实现
int det_matrix(Matrix& mat, int row)//可以求解行列式的必为反正,所以只传入行数即可
{
if(row == 2)
//当递归到一个二维矩阵时我们可以直接求解行列式
{
double* arr = mat.get_mat();
return arr[0 * row + 0] * arr[1 * row + 1] - arr[0 * row + 1] * arr[1 * row + 0];
//用一维数组,存储arr[(所在行数 - 1)* mat_row + 所在列数] 即代表第0行
}
else
//递归步骤 -- 每个小问题的解决方法
{
double res = 0;
double *vec = mat.get_mat();
for(int i = 0; i < row; i++)
//为方便编写程序,每个矩阵都由第一行展开
{
int k = 1;
if(i % 2 == 1)
{
k = -1;
}
Matrix new_mat = remove_row_col(mat,1, i + 1);
//remove_row_col()返回一个去掉特定行和列的矩阵;
res += vec[i] * k * det(new_mat,row - 1);
}
return res;
}
Matrix remove_row_col(Matrix &m,int row, int col)
{
int old_row = m.get_row();
int old_col = m.get_col();
int new_row = m.get_row() - 1;
int new_col = m.get_col() - 1;
double *arr = m.get_mat();
double new_mat = new double[(new_row * new_col];
int old_size = old_row * old_col;
int j = 0;
for(int i = 0; i < old_size; i++)
//遍历原来的矩阵
{
if(i % old_col== col - 1 || i / old_col == row - 1)
//去除掉处于所在列和行的元素
{
continue;
}
else
{
new_mat[j++] = arr[i]
}
}
Matrix new_matrix(new_mat,new_row,new_col);
return new_matrix;
}