如和编写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;
}

};

运行结果及报错内容

不知道如何求逆矩阵

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

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

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;
}


还有如何从文件中读取矩阵进行运算

您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!
PS:问答VIP年卡 【限时加赠:IT技术图书免费领】,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632