m0_72524251 2022-07-05 23:40 采纳率: 77.8%

# 矩阵运算，如何才能正确的得到结果

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

#include
#include
#include //vector函数所包含的库
#include //调用reverse函数所包含的库
#include
using namespace std;
#include
using namespace std;
class matrix
{
public:
int r, c; //r表示行，c表示列
double** mem;
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)
{
double ret = getA(m);
/*matrix inverse(m.r, m.c);
for (int i = 0; i < r; i++)
for (int j = 0; j < m.c; j++)
inverse.mem[i][j] = 0;*/
matrix inverse = getAStart(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] = inverse.mem[i][j] / ret;
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 print(const 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;
}
``````

};

{
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];
}
}
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];
}
}
is.close();
``````

}

int main()
{
char oper;
cout << "请输入" << endl;
cin >> oper;
matrix mem1(3, 3), mem2(3, 3);
matrix p3 = mem1 + mem2;
p3.print(p3);

``````return 0;
``````

}

• 写回答

#### 3条回答默认 最新

• 关注

另外，你的matrix类中，没有无参构造函数，如果你在main函数中，直接把矩阵的行数和列数写死了，会导致内存泄漏。需要添加一个无参构造函数。
修改后运行结果：

代码修改如下：

``````#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 ，不能计算逆矩阵。" << endl;
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[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[] bb;
}

matrix& operator=(const matrix& m)
{

if (this->mem != 0)
{
for (int i = 0; i < r; i++)
delete[] this->mem[i];
delete[] this->mem;
}
r = m.r;
c = m.c;

this->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] = 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 file()
{
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();
}
void test01()
{
char oper;
cout << "请输入符号（+，-，*，/）：" << endl;
cin >> oper;
matrix mem1, mem2, result;
file();
mem1.print();
mem2.print();

switch (oper)
{
case'+':
result = mem1 + mem2;
break;
case'-':
result = mem1 - mem2;
break;
case'*':
result = mem1 * mem2;
break;
case'/':
result = mem1.matrixinvers();
break;
default:
cout << "请输入正确的运算符。" << endl;
}
result.print();
}

int main()
{
test01();
return 0;
}

``````
本回答被题主选为最佳回答 , 对您是否有帮助呢?
评论 编辑记录

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

#### 悬赏问题

• ¥18 深度学习tensorflow1，ssdv1，coco数据集训练一个模型
• ¥100 关于注册表摄像头和麦克风的问题
• ¥30 代码本地运行正常，但是TOMCAT部署时闪退
• ¥15 关于#python#的问题
• ¥15 主机可以ping通路由器但是连不上网怎么办
• ¥15 数据库一张以时间排好序的表中，找出多次相邻的那些行
• ¥50 关于DynamoRIO处理多线程程序时候的问题