用c++实现矩阵的运算以及用矩阵的方式输出矩阵

任务需求:需要写一个矩阵的四则运算的小demo,通过重载运算符来实现。

需要实现:
  • matrix的构造函数
    动态开辟空间,实现添加矩阵。

  • 析构函数
    释放动态开辟的空间,防止内存泄露。

  • 重载“+ - * /”运算符

  • 为了方便输出 顺便实现 << 运算符

矩阵运算规则

百度到的运算规则

简单来说一下吧:

  1. 加减法
    同型矩阵,对应位置相加减。
    add
  2. 数乘
    分别于矩阵中的每一位相乘。
    在这里插入图片描述
  3. 矩阵乘矩阵(点积)
    文字表示:
      (1) 行数与(左矩阵)A相同,列数与(右矩阵)B相同,即.
      (2) C的第行第列的元素由A的第行元素与B的第列元素对应相乘,再取乘积之和.
    图说话:
    在这里插入图片描述

难点

  1. 多维矩阵的存储
    为了方便实现,采用一维数组的存储方式,将多维数组按照一定的规律存储为一维。
    可以通过偏移的方式找到其他的元素,但是这里没有必要。
  2. 实现 << 运算符
    实现类似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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值