C++实现求解逆矩阵

利用C语言求解线性代数中求解逆矩阵的一类问题。

最近在学线代,其中有一个挺烦人的就是求解逆矩阵,虽然求逆矩阵不难,但我自己在解题的时候经常求错,所以就想能不能用算法来求解这一类的题目。

求解逆矩阵一般可以用初等行变换或伴随矩阵方法求解。

这里采用的是伴随矩阵方法。

思路很简单,先求矩阵A对应的行列式|A|,然后在求伴随矩阵即可,伴随矩阵可以用一个二维数组存放即可,注意一下伴随矩阵的元素排列方式,还有稍微注意一下在行列式中的元素下标和二维数组中的下标的不同。

接下来就是如何求解|A|的问题了,我没想太多,直接暴力求解吧,反正我需要求的阶数不会很多,所以即使算法不优,运行时间也不会很长。这里用的是余子式的方法,从第一行的第一个元素开始,得到对应的余子式,为了能够计算余子式的值,还需要继续对余子式求余子式,这里利用递归是一个很好的方法,会让思路很清晰。

至于伴随矩阵,实际上也是求解余子式的过程,这个过程和上述几乎是一样的。

下面是程序代码:carray.cpp

#include<iostream>
#include<iomanip>
using namespace std;
#define N 10 //行列式的最大阶数
int getvalue(int a[N][N],int n){ //计算|A|    
    if(n==1) //递归结束条件,当n=1时,得到返回值a00;
        return a[0][0];    
    int res = 0,i,j,k,t,temp[N][N];   //定义一个临时数组,用于存放Ai的余子式  
    for(i=0;i<n;i++){  
        for(j=0;j<n-1;j++)  
            for(k=0;k<n-1;k++)  
                temp[j][k] = a[j+1][(k>=i)?k+1:k];        //每执行完一次j,k的循环,二位数组temp就是Ai的余子式
        t = getvalue(temp,n-1);  //递归,再求数组temp的第一行的余子式,直到余子式只有1个元素
        if(i&1)  //确定余子式的符号并进行行列式运算
            res -=  a[0][i]*t; 
        else    
            res += a[0][i]*t;  
    }  
    return res; //返回行列式计算结果
}  
void getAStar(int a[N][N],int n,int yu[N][N]){ //计算每一行每一列的每个元素所对应的余子式,组成A*    
    if(n==1)  
        yu[0][0] = 1; //若阶数为1,则没有余子式    
    int i,j,k,t;  
    int temp[N][N];  
    for(i=0;i<n;i++)  
        for(j=0;j<n;j++){  
            for(k=0;k<n-1;k++)  
                for(t=0;t<n-1;t++)  
                    temp[k][t] = a[k>=i?k+1:k][t>=j?t+1:t]; 
//到这里,temp存放的是a[0][0]的余子式(当然对应到数学时这里就是元素a11的余子式了)
yu[j][i]  =  getvalue(temp,n-1);    
//同理,将余子式结果直接赋给yu[j][i]就可以了,这里为什么是ji而不是ij?                         
//因为这是伴随矩阵的排列方式决定的
            if((i+j)&1)  
                yu[j][i] = - yu[j][i];               //同样要判断符号
        }    
}  
  
int main()  
{  
    int arr[N][N],res[N][N];  
    int i,j;  
    int n; 
cout<<"/*********************本程序可以求解10阶以内矩阵的逆矩阵**********************/"<<endl;
cout<<"请输入矩阵的阶数:"<<endl;
    while(cin>>n && n){  
cout<<"请输入矩阵:"<<endl;
        for(i=0;i<n;i++)  
            for(j=0;j<n;j++)     
                cin>>arr[i][j];
cout<<"所求得的逆矩阵为:"<<endl;
        int a = getvalue(arr,n);
        if(a==0)   
            cout<<"can not transform!"<<endl;   
        else{  
            getAStar(arr,n,res);  
            for(i=0;i<n;i++){  
                for(j=0;j<n;j++){ 
double c=(double)res[i][j]/a;//A-1=1/|A|*A*;
if(c==(int) c)
cout<<setw(6)<<(int)c;//如果是整数则直接输出整数,每个字段长度为6
// cout<<setiosflags(ios::fixed)<<setiosflags(ios::right)<<setprecision(5);
else
cout<<setw(6)<<setiosflags(ios::fixed)<<setiosflags(ios::left)<<setprecision(3)<<c;
//如果不是整数则输出浮点数,设置小数位数为3,小数点符号对齐              
}
                cout<<endl;  
}
        }  
        cout<<endl;
cout<<"请输入矩阵的阶数:"<<endl;
    } 
    return 0;  
}  


  • 8
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值