任務需求:需要寫一個矩陣的四則運算的小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;
}