嘛。。因为一道水题做不出来而被大佬鄙视的我决定让计算机来做(我不信大佬还能够有计算机快2333
稍微写了点代码实现了求行列式的功能。如果有时间的话说不定会把求逆也给码了(咕咕咕
#include<iostream>
#include<stdlib.h>
using namespace std;
void input(double *a,int n,int m){//输入n行m列的a
cout<<"请输入一个"<<n<<"*"<<m<<"的矩阵\n";
for (int i=0;i<n;i++)
for (int j=0;j<m;j++)cin>>a[i*n+j];
}
void print(double *a,int n,int m){//打印矩阵
for (int i=0;i<n;i++){
for (int j=0;j<m;j++)cout<<a[i*m+j]<<" ";
cout<<endl;
}
return ;
}
double det(double*,int);//声明行列式函数
void det_use();
main (){
int choose ;
while (1){
printf("请输入一个数字\n0.退出程序\n1.计算行列式\n2.求矩阵的逆");
cin>>choose;
if (choose==1)cheng();
else if (choose==0){cout<<"感谢使用";break;}
else if (choose==1)det_use();
else if (choose==2)contrary_use();
}
return 0;
}
void divide_Matrix(double *a,double*b,double p,int n){//将n列的a行乘p减到第b行
for (int i=0;i<n;i++)
b[i]-=a[i]*p;
return ;
}
void swap_Matrix(double **a,double **b){//对矩阵做列变换
double *tmp;
tmp=*a;
*a=*b;
*b=tmp;
return;
} //这里曾犯了一个错误,定义了double**tmp,然后进行运算,即野指针然后gg了
void clean_Matrix(double **p,int i,int n){//p[i]指向的是第i行 ,将第i+1到第n行的第i列全部变成0
for (int j=i+1;j<n;j++){
divide_Matrix(p[i],p[j],p[j][i]/p[i][i],n);
}
return;
}
double det(double*a,int n){//用高斯消元法化为上三角行列式求值
double **p=(double**)malloc(sizeof(double*)*n);
for (int i=0;i<n;i++)p[i]=a+i*n;//将p[i][j]与之对应
//先对第一列进行
int sgn=1,i=0,j=0;
bool c;
for (i=0;i<n;i++){
c=0;
for (j=i;j<n;j++){//从第i行开始找
if (p[j][i])//若第j行i列不为0,那么就可以把第j行和第i行换个位置
{
c=1;//需要判定有没有一个非0的数如果没有应该返回0
if(j==i) //在这里我需要将其之下的所有第i列的减掉所以我们编写一个函数来完成这一件事
{clean_Matrix(p,i,n);break;}
else if (j>i){
swap_Matrix(&p[i],&p[j]);
sgn*=-1;
clean_Matrix(p,i,n);
break;
}
}
}
// for (int i=0;i<n;i++)print(p[i],1,n),cout<<endl;
if (!c)return 0;
}
double deta=1;
for (int i=0;i<n;i++)deta*=p[i][i];
deta*=sgn;
return deta;
}
void det_use(){
int n;
cout<<"请输入矩阵的阶数\n";
cin>>n;
double *p=(double*)malloc(sizeof(double)*n*n);
cout<<"请输入矩阵的项\n";
for (int i=0;i<n;i++)
for (int j=0;j<n;j++)cin>>p[i*n+j];
cout<<"此矩阵的行列式的值为:\n";
cout<<det(p,n)<<endl;
return;
}
之后因为闲的蛋疼就又把求矩阵的逆的代码给写出来了,用的仍然是高斯消元法
下面是核心算法
void contrary(double **p,double **I,int n){//p,I是指向行的指针所以 p[i][j]指的是第i行j列的元素 ,p是所输入的矩阵I是单位矩阵
for (int i=0;i<n;i++)//仍然是从列开始考虑
{
for (int j=i;j<n;j++){
if (p[i][j]){
if (i!=j){
double*tmp;
tmp=p[i];
p[i]=p[j];
p[j]=tmp;
tmp=I[i];
I[i]=I[j];
I[j]=tmp;
}
for (int k=i+1;k<n;k++){
divide_Matrix(I[i],I[k],p[k][i]/p[i][i],n);
divide_Matrix(p[i],p[k],p[k][i]/p[i][i],n);
// print(*p,n,n);cout<<endl;print(*I,n,n);cout<<endl;
}
}
else if (p[i][j]==0)continue;
break;
}
}//此时p应该已经被变换成上三角矩阵,我们考虑将其继续消元 ,为此我们设置一个对列进行操作的函数(这里错了,又进行行变换又进行列变换其实是即左乘又右乘,不能得到答案
for (int i=n-1;i>=0;i--){
for (int j=i-1;j>=0;--j){
divide_Matrix(I[i],I[j],p[j][i]/p[i][i],n);
divide_Matrix(p[i],p[j],p[j][i]/p[i][i],n);
// print(*p,n,n),cout<<endl;print(*I,n,n);cout<<endl;
}
}//这时候p就应该已经是一个对角矩阵
//现在来处理对角矩阵的情况
for (int i=0;i<n;i++)multply_Matrix_line(I[i],p[i][i],n),multply_Matrix_line(p[i],p[i][i],n);
return;
}
其中divide_Matrix(doublea,doubleb,double p,int n)是一个作用为把a指向的n个元素乘p减到b指向的n个元素。
不过在运行这个程序之前需要判断其行列式为不为0;
这个用上面的det函数即可说明
void contrary_use(){
int n;
cout<<"请输入矩阵的阶数\n";
cin>>n;
double *a=(double*)malloc(sizeof(double)*n*n);
double *b=(double*)malloc(sizeof(double)*n*n);
input(a,n,n);
for (int i=0;i<n;i++)
for (int j=0;j<n;j++)
b[i*n+j]=a[i*n+j];
double res_of_det_a=det(b,n);
if (res_of_det_a==0){cout<<"这个"<<n<<"阶矩阵的行列式值为0,不可逆\n";return ;}
else cout<<"这个"<<n<<"阶矩阵的行列式值为"<<res_of_det_a<<"\n其逆为:\n";
double *I=(double*)malloc(sizeof(double)*n*n);
for (int i=0;i<n;i++)
for (int j=0;j<n;j++){if (j==i)I[i*n+j]=1;
else I[i*n+j]=0;
}
double **p=(double**)malloc(sizeof(double*)*n);
double **I1=(double**)malloc(sizeof(double*)*n);
for (int i=0;i<n;i++)p[i]=a+i*n,I1[i]=I+i*n;
contrary(p,I1,n);
for (int i=0;i<n;i++)//这里曾出现过一个问题,就是直接套用input函数却忘了进行行变换时input的输出顺序不变
{
for (int j=0;j<n;j++)cout<<I1[i][j]<<" ";
cout<<endl;
}
// cout<<endl; print(*p,n,n);
return;
}