m0_72524251 2022-07-05 13:07 采纳率: 77.8%
浏览 65
已结题

如和编写c++求逆矩阵

问题遇到的现象和发生背景

如何编写一个类来求逆矩阵

问题相关代码,请勿粘贴截图

#include
#include
#include //vector函数所包含的库
#include //调用reverse函数所包含的库
#include
using namespace std;
#include
using namespace std;
class matrix {
public:
int r, c; //r表示行,c表示列
int** mem;
matrix(int a, int b):r(a),c(b)
{
mem = new int* [a]; //堆区开辟一段内存 程序结束后需要手动释放
for (int i = 0; i < a; i++)
{
mem[i] = new int[b];
}
};
matrix(const matrix& p) //拷贝构造函数
{
r = p.r;
c = p.c;
mem = new int* [r]; //深拷贝,在堆区重新开辟一段内存,避免析构函数释放内存时重复释放同一块内存时而出错
for (int i = 0; i < r; i++)
{
mem[i] = new int[c];
}
for (int i = 0; i < r; i++)
for (int j = 0; j < c; j++) {
mem[i][j] = p.mem[i][j];
}
}
~matrix() //析构函数,释放在堆区开辟的内存
{
for (int i = 0; i < r; i++) {
delete[]mem[i];
}
delete[]mem;
};

//+运算符重载   也可以用全局函数来重载   matrix  operatior+(const matrix& m1,const matrix& m2)
matrix operator+ (const matrix& m)     
{
    if (r != m.r || c != m.c)   //判断是否为同型矩阵
    {
        cout << "请输入正确的类型的矩阵。";
        matrix tmp(r, c);         //调用构造函数
        tmp.mem = NULL;           //将该二维指针置空,避免出现野指针的情况
        return tmp;
    }
    else {
        matrix tmp(r, c);
        for (int i = 0; i < r; i++)
            for (int j = 0; j < c; j++)
                tmp.mem[i][j] = mem[i][j] + m.mem[i][j];
        return tmp;
    }
}
matrix operator- (const matrix& m) 
{
    if (r != m.r || c != m.c)//判断是否符合相减的条件
    {
        cout << "请输入正确的类型的矩阵。";
        matrix tmp(r, c);
        tmp.mem = NULL;
        return tmp;
    }
    else {
        matrix tmp(r, c);
        for (int i = 0; i < r; i++)
            for (int j = 0; j < c; j++)
                tmp.mem[i][j] = mem[i][j] - m.mem[i][j];
        return tmp;
    }
}
matrix operator* (const matrix& m)//矩阵乘
{
    if (c != m.r) {
        cout << "请输入正确的类型的矩阵。";
        matrix tmp(r, c);
        tmp.mem = NULL;
        return tmp;
    }
    else {
        matrix tmp(r, m.c);
        for (int i = 0; i < r; i++)
            for (int j = 0; j < m.c; j++)
                tmp.mem[i][j] = 0;//初始化二维数组
        for (int i = 0; i < tmp.r; i++)
            for (int j = 0; j < tmp.c; j++)
                for (int k = 0; k < c; k++)
                    tmp.mem[i][j] += (mem[i][k] * m.mem[k][j]);
        return tmp;
    }
}

//求逆运算
matrix operator/(const matrix& m)
{
    double ret = getA(m);

    if (m.r != m.c||ret==0)
    {
        cout << "请输入正确的类型的矩阵。";
        matrix tmp(r, c);
        tmp.mem = NULL;
        return tmp;
    }
    else
    {
        matrix tmp(m.r, m.c);
        for (int i = 0; i < r; i++)
            for (int j = 0; j < m.c; j++)
                tmp.mem[i][j] = 0;//初始化二维数组
        for (int i = 0; i < tmp.r; i++)
            for (int j = 0; j < tmp.c; j++)
                    tmp.mem[i][j] =
        return tmp;
        
    }
}


//按第一行展开计算|A|
double getA(const matrix&m)
{

    if (m.r == 1&&m.c==1)
    {
        return mem[0][0];
    }
    double ans = 0;
    matrix tmp(r, m.c);
    for (int i = 0; i < r; i++)
        for (int j = 0; j < m.c; j++)
            tmp.mem[i][j] = 0;//初始化二维数组
    int i, j, k;
    for (i = 0; i < m.r; i++)
    {
        for (j = 0; j < m.r - 1; j++)
        {
            for (k = 0; k < m.r - 1; k++)
            {
                tmp.mem[j][k] = mem[j + 1][(k >= i) ? k + 1 : k];

            }
        }
        double t = getA(tmp);
        if (i % 2 == 0)
        {
            ans += tmp.mem[0][i] * t;
        }
        else
        {
            ans -= tmp.mem[0][i] * t;
        }
    }
    return ans;
}

//计算每一行每一列的每个元素所对应的余子式,组成A*
matrix  getAStart(const matrix& m)
{
    if (m.r == 1&&m.c==1)
    {
        matrix tmp(r, c);
        tmp.mem[0][0] = 1;
        return tmp;
    }
    matrix tmp(r, m.c);
    for (int i = 0; i < r; i++)
        for (int j = 0; j < m.c; j++)
            tmp.mem[i][j] = 0;//初始化二维数组
    int i, j, k, t;
    for (i = 0; i < m.r; i++)
    {
        for (j = 0; j < m.r; j++)
        {
            for (k = 0; k < m.r; k++)
            {
                for (t = 0; t < m.r; t++)
                {
                    tmp.mem[k][t] = mem[k >= i ? k + 1 : k][t >= j ? t + 1 : t];
                }
            }
            tmp.mem[j][i] = getA(tmp);
            if ((i + j) % 2 == 1)
            {
                mem[j][i] = -mem[j][i];
            }
        }
        return *this;
    }
}
matrix& operator=(const matrix& m)
{
    if (c != m.r) {
        cout << "请输入正确的类型的矩阵。";
        matrix tmp(r, c);
        tmp.mem = NULL;
        return tmp;
    }
    else {
        for (int i = 0; i < r; i++)
            for (int j = 0; j < c; j++)
                mem[i][j] = m.mem[i][j];
        return *this;
    }
}
 void display(matrix m)//输出矩阵
{
    for (int i = 0; i < m.r; i++) {
        for (int j = 0; j < m.c; j++) {
            cout << m.mem[i][j] << ' ';
        }
        cout << endl;
    }
    cout << "====================================================================================" << endl;
}

};

运行结果及报错内容

不知道如何求逆矩阵

我的解答思路和尝试过的方法
我想要达到的结果
  • 写回答

3条回答 默认 最新

  • 关注

    代码给你修改了,读文件的也在,运行结果如下:

    img

    #include <iostream>
    #include <fstream>
    using namespace std;
    
    class matrix
    {
    public:
        int r, c; //r表示行,c表示列
        double** mem;
    
        //这里添加2个无参构造函数
        matrix() { r = 0, c = 0, mem = 0; }
        matrix(int a, int b, double* p)
        {
            r = a;
            c = b;
            mem = new double* [a]; //堆区开辟一段内存 程序结束后需要手动释放
            for (int i = 0; i < a; i++)
            {
                mem[i] = new double[b];
                for (int j = 0; j < b; j++)
                    mem[i][j] = p[i * b + j];
            }
        }
    
        matrix(int a, int b) :r(a), c(b)
        {
            mem = new double* [a]; //堆区开辟一段内存 程序结束后需要手动释放
            for (int i = 0; i < a; i++)
            {
                mem[i] = new double[b];
            }
        };
        matrix(const matrix& p) //拷贝构造函数
        {
            r = p.r;
            c = p.c;
            mem = new double* [r]; //深拷贝,在堆区重新开辟一段内存,避免析构函数释放内存时重复释放同一块内存时而出错
            for (int i = 0; i < r; i++)
            {
                mem[i] = new double[c];
            }
            for (int i = 0; i < r; i++)
                for (int j = 0; j < c; j++) {
                    mem[i][j] = p.mem[i][j];
                }
        }
        ~matrix() //析构函数,释放在堆区开辟的内存
        {
            for (int i = 0; i < r; i++) {
                delete[]mem[i];
            }
            delete[]mem;
        };
    
        //+运算符重载   也可以用全局函数来重载   matrix  operatior+(const matrix& m1,const matrix& m2)
        matrix operator+ (const matrix& m)
        {
            if (r != m.r || c != m.c)   //判断是否为同型矩阵
            {
                cout << "请输入正确的类型的矩阵。";
                matrix tmp(r, c);         //调用构造函数
                tmp.mem = NULL;           //将该二维指针置空,避免出现野指针的情况
                return tmp;
            }
            else {
                matrix tmp(r, c);
                for (int i = 0; i < r; i++)
                    for (int j = 0; j < c; j++)
                        tmp.mem[i][j] = mem[i][j] + m.mem[i][j];
                return tmp;
            }
        }
        matrix operator- (const matrix& m)
        {
            if (r != m.r || c != m.c)//判断是否符合相减的条件
            {
                cout << "请输入正确的类型的矩阵。";
                matrix tmp(r, c);
                tmp.mem = NULL;
                return tmp;
            }
            else {
                matrix tmp(r, c);
                for (int i = 0; i < r; i++)
                    for (int j = 0; j < c; j++)
                        tmp.mem[i][j] = mem[i][j] - m.mem[i][j];
                return tmp;
            }
        }
        matrix operator* (const matrix& m)//矩阵乘
        {
            if (c != m.r) {
                cout << "请输入正确的类型的矩阵。";
                matrix tmp(r, c);
                tmp.mem = NULL;
                return tmp;
            }
            else {
                matrix tmp(r, m.c);
                for (int i = 0; i < r; i++)
                    for (int j = 0; j < m.c; j++)
                        tmp.mem[i][j] = 0;//初始化二维数组
                for (int i = 0; i < tmp.r; i++)
                    for (int j = 0; j < tmp.c; j++)
                        for (int k = 0; k < c; k++)
                            tmp.mem[i][j] += (mem[i][k] * m.mem[k][j]);
                return tmp;
            }
        }
    
        //求逆运算
        //matrix operator/(const matrix& m)
        matrix matrixinvers()
        {
            //double ret = getA(m);
    
            if (r != c /* || ret == 0*/)
            {
                cout << "请输入正确的类型的矩阵。";
                matrix tmp(r, c);
                tmp.mem = NULL;
                return tmp;
            }
            else
            {
                double* p = new double[r * c];
                int k = 0;
                for (int i = 0; i < r; i++)
                {
                    for (int j = 0; j < c; j++)
                        p[k++] = mem[i][j];
                }
                inverse(r, p);
                matrix tmp(r,c,p);
                return tmp;
            }
        }
    
        double det(int n, double* aa)
        {
            if (n == 1)
                return aa[0];
            double* bb = new double[(n - 1) * (n - 1)];//创建n-1阶的代数余子式阵bb    
            int mov = 0;//判断行是否移动   
            double sum = 0.0;//sum为行列式的值  
            for (int arow = 0; arow < n; arow++) // a的行数把矩阵a(nn)赋值到b(n-1)  
            {
                for (int brow = 0; brow < n - 1; brow++)//把aa阵第一列各元素的代数余子式存到bb  
                {
                    mov = arow > brow ? 0 : 1; //bb中小于arow的行,同行赋值,等于的错过,大于的加一  
                    for (int j = 0; j < n - 1; j++)  //从aa的第二列赋值到第n列  
                    {
                        bb[brow * (n - 1) + j] = aa[(brow + mov) * n + j + 1];
                    }
                }
                int flag = (arow % 2 == 0 ? 1 : -1);//因为列数为0,所以行数是偶数时候,代数余子式为1.  
                sum += flag * aa[arow * n] * det(n - 1, bb);//aa第一列各元素与其代数余子式积的和即为行列式
            }
            delete[] bb;
            return sum;
        }
    
        
    
        void inverse(int n, double* aa)
        {
            double det_aa = det(n, aa);
            //cout << "输入矩阵的行列式:" << det_aa << endl;
            if (det_aa == 0)
            {
                cout << "行列式为0 ,不能计算逆矩阵。\n";
                return;
            }
    
    
            double* adjoint = new double[n * n];
            double* bb = new double[(n - 1) * (n - 1)];//创建n-1阶的代数余子式阵bb   
    
            int pi, pj, q;
            for (int ai = 0; ai < n; ai++) // a的行数把矩阵a(nn)赋值到b(n-1)  
            {
                for (int aj = 0; aj < n; aj++)
                {
                    for (int bi = 0; bi < n - 1; bi++)//把元素aa[ai][0]代数余子式存到bb[][]  
                    {
                        for (int bj = 0; bj < n - 1; bj++)//把元素aa[ai][0]代数余子式存到bb[][]  
                        {
                            if (ai > bi)    //ai行的代数余子式是:小于ai的行,aa与bb阵,同行赋值  
                                pi = 0;
                            else
                                pi = 1;     //大于等于ai的行,取aa阵的ai+1行赋值给阵bb的bi行  
                            if (aj > bj)    //ai行的代数余子式是:小于ai的行,aa与bb阵,同行赋值  
                                pj = 0;
                            else
                                pj = 1;     //大于等于ai的行,取aa阵的ai+1行赋值给阵bb的bi行  
    
                            bb[bi * (n - 1) + bj] = aa[(bi + pi) * n + bj + pj];
                        }
                    }
                    /*printf("aa[%d][%d]的余子式\n", ai, aj);
                    for (int i = 0; i < n - 1; i++)
                    {
                        for (int j = 0; j < n - 1; j++)
                        {
                            printf("%lf     ", bb[i * (n - 1) + j]);
                        }
                        printf(" \n");
                    }*/
                    if ((ai + aj) % 2 == 0)  q = 1;//因为列数为0,所以行数是偶数时候,代数余子式为-1.  
                    else  q = (-1);
                    adjoint[ai * n + aj] = q * det(n - 1, bb);
                }
            }
            for (int i = 0; i < n; i++)//adjoint 转置
            {
                for (int j = 0; j < i; j++)
                {
                    int tem = adjoint[i * n + j];
                    adjoint[i * n + j] = adjoint[j * n + i];
                    adjoint[j * n + i] = tem;
                }
            }
            /*printf("伴随阵: \n");
            for (int i = 0; i < n; i++) //打印伴随阵
            {
                for (int j = 0; j < n; j++)
                {
                    cout << adjoint[i * n + j] << "\t";
                }
                cout << endl;
            }
            printf("逆矩阵: \n");*/
            for (int i = 0; i < n; i++) //打印逆矩阵
            {
                for (int j = 0; j < n; j++)
                {
                    aa[i * n + j] = adjoint[i * n + j] / det_aa;
                    //cout << aa[i * n + j] << "\t";
                }
                //cout << endl;
            }
            delete[] adjoint;
            delete[] bb;
        }
    
    
    
        //按第一行展开计算|A|
        double getA(const matrix& m)
        {
    
            if (m.r == 1 && m.c == 1)
            {
                return mem[0][0];
            }
            double ans = 0;
            matrix tmp(m.r, m.c);
            for (int i = 0; i < m.r; i++)
                for (int j = 0; j < m.c; j++)
                    tmp.mem[i][j] = 0;//初始化二维数组
            int i, j, k;
            for (i = 0; i < m.r; i++)
            {
                for (j = 0; j < m.r - 1; j++)
                {
                    for (k = 0; k < m.r - 1; k++)
                    {
                        tmp.mem[j][k] = mem[j + 1][(k >= i) ? k + 1 : k];
    
                    }
                }
                double t = getA(tmp);
                if (i % 2 == 0)
                {
                    ans += tmp.mem[0][i] * t;
                }
                else
                {
                    ans -= tmp.mem[0][i] * t;
                }
            }
            return ans;
        }
    
        //计算每一行每一列的每个元素所对应的余子式,组成A*
        matrix  getAStart(const matrix& m)
        {
            if (m.r == 1 && m.c == 1)
            {
                matrix tmp(r, c);
                tmp.mem[0][0] = 1;
                return tmp;
            }
            matrix tmp(r, m.c);
            for (int i = 0; i < r; i++)
                for (int j = 0; j < m.c; j++)
                    tmp.mem[i][j] = 0;//初始化二维数组
            int i, j, k, t;
            for (i = 0; i < m.r; i++)
            {
                for (j = 0; j < m.r; j++)
                {
                    for (k = 0; k < m.r; k++)
                    {
                        for (t = 0; t < m.r; t++)
                        {
                            tmp.mem[k][t] = mem[k >= i ? k + 1 : k][t >= j ? t + 1 : t];
                        }
                    }
                    tmp.mem[j][i] = getA(tmp);
                    if ((i + j) % 2 == 1)
                    {
                        mem[j][i] = -mem[j][i];
                    }
                }
                return *this;
            }
        }
        matrix& operator=(const matrix& m)
        {
            if (c != m.r) {
                cout << "请输入正确的类型的矩阵。";
                matrix tmp(r, c);
                tmp.mem = NULL;
                return tmp;
            }
            else {
                for (int i = 0; i < r; i++)
                    for (int j = 0; j < c; j++)
                        mem[i][j] = m.mem[i][j];
                return *this;
            }
        }
        void print()//输出矩阵
        {
            for (int i = 0; i < r; i++) {
                for (int j = 0; j < c; j++) {
                    cout << mem[i][j] << ' ';
                }
                cout << endl;
            }
            cout << endl;
        }
    };
    
    void matrixRead(matrix& m1, matrix& m2)
    {
        ofstream ofs;
        ofs.open("matrix1.txt", ios::out);
        ofs << 3 << " " << 3 << endl;
        ofs << 1 << " " << 2 << " " << 3 << endl;
        ofs << 2 << " " << 4 << " " << 5 << endl;
        ofs << 3 << " " << 5 << " " << 7 << endl;
        ofs << 3 << " " << 3 << endl;
        ofs << 2 << " " << 4 << " " << 6 << endl;
        ofs << 3 << " " << 7 << " " << 9 << endl;
        ofs << 1 << " " << 5 << " " << 7 << endl;
        ofs.close();
    
        double** mem1, ** mem2;
        ifstream is;
        is.open("matrix1.txt", ios::in);
        if (!is.is_open())
        {
            cout << "文件打开失败" << endl;
            return;
        }
        //读取文件的行和列
        int r, c;
        is >> r >> c;
        mem1 = new double* [r];
        for (int i = 0; i < r; i++)
            mem1[i] = new double[c];
        //开始读取
        for (int i = 0; i < r; i++)
        {
            for (int j = 0; j < c; j++)
            {
                is >> mem1[i][j];
            }
        }
    
        //给m1赋值
        m1.r = r;
        m1.c = c;
        m1.mem = mem1;
    
    
    
        is >> r >> c;
        mem2 = new double* [r];
        for (int i = 0; i < r; i++)
            mem2[i] = new double[c];
        //开始读取
        for (int i = 0; i < r; i++)
        {
            for (int j = 0; j < c; j++)
            {
                is >> mem2[i][j];
            }
        }
    
        //给m2赋值
        m2.r = r;
        m2.c = c;
        m2.mem = mem2;
    
        is.close();
    }
    
    int main()
    {
        char oper;
        cout << "请输入" << endl;
        cin >> oper;
        matrix mem1, mem2;
        matrixRead(mem1, mem2);
        matrix p3 = mem1 + mem2;
        p3.print();
    
        matrix m3 = mem1.matrixinvers();
        cout << "mem1的逆矩阵:"<<endl;
        m3.print();
    
        return 0;
    }
    
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 7月14日
  • 已采纳回答 7月6日
  • 创建了问题 7月5日

悬赏问题

  • ¥15 各位请问平行检验趋势图这样要怎么调整?说标准差差异太大了
  • ¥15 delphi webbrowser组件网页下拉菜单自动选择问题
  • ¥15 wpf界面一直接收PLC给过来的信号,导致UI界面操作起来会卡顿
  • ¥15 init i2c:2 freq:100000[MAIXPY]: find ov2640[MAIXPY]: find ov sensor是main文件哪里有问题吗
  • ¥15 运动想象脑电信号数据集.vhdr
  • ¥15 三因素重复测量数据R语句编写,不存在交互作用
  • ¥15 微信会员卡等级和折扣规则
  • ¥15 微信公众平台自制会员卡可以通过收款码收款码收款进行自动积分吗
  • ¥15 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab