任务需求:需要写一个矩阵的四则运算的小demo,通过重载运算符来实现。
需要实现:
-
matrix的构造函数
动态开辟空间,实现添加矩阵。 -
析构函数
释放动态开辟的空间,防止内存泄露。 -
重载“+ - * /”运算符
-
为了方便输出 顺便实现 << 运算符
矩阵运算规则
简单来说一下吧:
- 加减法
同型矩阵,对应位置相加减。
- 数乘
分别于矩阵中的每一位相乘。
- 矩阵乘矩阵(点积)
文字表示:
(1) 行数与(左矩阵)A相同,列数与(右矩阵)B相同,即.
(2) C的第行第列的元素由A的第行元素与B的第列元素对应相乘,再取乘积之和.
图说话:
难点
- 多维矩阵的存储
为了方便实现,采用一维数组的存储方式,将多维数组按照一定的规律存储为一维。
可以通过偏移的方式找到其他的元素,但是这里没有必要。 - 实现 << 运算符
实现类似Python中list输出的样式
想法: 递归
eg: [1,2,3,4,5,6,7,8] 为 2行4列 的数组
想要的输出为 [ [1,2,3,4],[5,6,7,8] ]
只有遍历到 最低维的时候才需要输出元素
如果将输出的list 看做一棵树 可以这么表示,存放元素的只有在叶子节点中,依次通过深度递归遍历将叶子节点依次输出即可。
一言不合上代码::
#include<iostream>
using namespace std;
class Matrix {
int* num;//各个维度的size
int* nums;//将矩阵转变为一维数组
int dimensionality;//维度
public:
Matrix(int x, int y) :Matrix(x, y, NULL, 0) {
}
//通过一维矩阵构造 多维矩阵不会传递TODO
//行数 列数 一维数组 数组的长度
Matrix(int x, int y, int* t_nums, int t_n) {
num = new int[2];
num[0] = x; num[1] = y;
dimensionality = 2;
int max_n = x * y;
nums = new int[max_n];
int min_dim = t_n < max_n ? t_n : max_n;
for (int i = 0; i < max_n; i++) {
if (i < min_dim)
this->nums[i] = t_nums[i];
else this->nums[i] = 0;
}
}
Matrix operator +(const Matrix& x) {
//判断是否是维度相同
int flag = true;//标志 同
if (this->dimensionality == x.dimensionality) {//判断维度是否相同
for (int i = 0; i < this->dimensionality; i++) {//判断各个维度size都相同
if (this->num[i] != x.num[i]) {
flag = false;
throw "两个矩阵的行数列数不相同!";
break;
}
}
}
else { flag = false; throw "维度不同,不能相加!"; }
//不同则不做处理,返回当前的矩阵
if (!flag)
return *this;
//因为没有保存nums数组的长度 需要计算
int sum_n = 1;//累成 是1****
for (int i = 0; i < x.dimensionality; i++) {
sum_n *= x.num[i];
}
//元素依次加
for (int i = 0; i < sum_n; i++) {
this->nums[i] += x.nums[i];
}
return *this;
}
Matrix() {
//赋值为NULL 不会造成内存泄漏 会进行指针检查 跳过NULL
num = NULL;
nums = NULL;
dimensionality = 0;
}
Matrix(const Matrix& m) {
this->dimensionality = m.dimensionality;
this->num = new int[m.dimensionality];
int sum_n = 1;
for (int i = 0; i < m.dimensionality; i++) {
this->num[i] = m.num[i];
sum_n *= m.num[i];
}
this->nums = new int[sum_n];
for (int i = 0; i < sum_n; i++) {
this->nums[i] = m.nums[i];
}
}
friend ostream& operator<< (ostream& out, const Matrix& m);
~Matrix() {
delete[] num;
}
};
//dim 维度 dunm 维度数组 记录各个维度 length 数组的长度 dunms 记录一维数组
void print(int dim, int* dnum, int length, int* dnums) {
dim--;
cout << "[";
//递归出口,当找到一维数组的时候就输出 "1,2,3,4]"的格式
if (dim == 0) {
for (int i = 0; i < dnum[dim]; i++) {
cout << dnums[i];
if (i != dnum[dim] - 1)cout << ",";
}
cout << "]";
return;
}
//不在一维的情况下就 进入循环,输出","分隔符
int capicity = length / dnum[dim];// 下一维的单位长度(一组)中的元素个数
int* temp_dnums = new int[capicity];
int zu = dnum[dim];//下一维需要分成多少组,就是:比如当前2行3列就是2即 低一纬的个数
int t = 0;
while (zu--) {
for (int i = 0; i < capicity; i++, t++) {
temp_dnums[i] = dnums[t];
}
print(dim, dnum, capicity, temp_dnums);//递归输出
if (zu)cout << ",\n";
}
cout << "]";
}
ostream& operator<< (ostream& out, const Matrix& m) {
cout << "矩阵运算的结果是:" << endl;
int sum_n = 1;
for (int i = 0; i < m.dimensionality; i++) {
sum_n *= m.num[i];
}
int* temp_num = new int[m.dimensionality];
for (int i = 0; i < m.dimensionality; i++) {//将维度的存储翻转,供分组使用
(temp_num[m.dimensionality - i - 1] = m.num[i]);
}
print(m.dimensionality, temp_num, sum_n, m.nums);
return out;
}
int main() {
int s[] = { 1,2,3,4,5,6 };
Matrix m1(3, 2, s, 6);
int s2[] = { 2, 3, 4, 5, 6, 7, 8 };
Matrix m2(2, 2, s2, 5);
Matrix m3(3, 2, s2, 5);
cout << "两个(3,2)矩阵相加:" << endl;
cout << m1 + m3 << endl;
puts("");
Matrix m4(2, 3, s, 6);
Matrix m5(2, 3, s2, 5);
cout << "两个(2,3)矩阵相加:" << endl;
cout << m4 + m5 << endl;
puts("");
try {
cout << "行数,列数不相同时的矩阵相加:" << endl;
cout << m1 + m2 << endl;
}
catch (const char* msg) {
cout << msg << endl;
}
return 0;
}