趁着线性代数的知识还热乎,简短的写了个矩阵类的demo,目前实现了
- 矩阵的构造
- 矩阵的运算(+ - * =)
- 矩阵的读写
需不断更新…(对角矩阵、求矩阵的逆、伴随矩阵、对称矩阵、特征值与特征向量、矩阵相似判断、是否可对角化、二次型等实际需要时再继续学习)
矩阵类
该矩阵类包含三个私有变量,用二维容器存储矩阵中的元素值,用两个整型变量存储矩阵的行数和列数。参数的获取通过特定的函数返回,类外不能直接访问。
目前该类实现了矩阵的加减法及乘法的功能,矩阵的打印与写入文件操作。其他功能以后慢慢更新。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| template<class T> class Matrix { public: Matrix(int row, int line); Matrix(const Matrix& m); Matrix(int row, int line, const vector<T> nums); int getRow() const{ return m_row; } int getLine()const { return m_line; } T getValue(int i, int j) const{ return mat[i][j]; } void MatPrint(); void MatWrite(string file_name); Matrix operator+(const Matrix& p); Matrix operator*(const Matrix& p); private: vector< vector<T> > mat; int m_row; int m_line; };
|
构造函数
构造函数有三种形式,两个普通构造函数和一个拷贝构造函数
普通构造函数必须提供待构造矩阵的行列数,矩阵元素的值可通过vector
容器传入
若不传入矩阵元素值,则默认为0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| template<class T> Matrix<T>::Matrix(int row, int line) { mat.resize(row, vector<T>(line, 0)); m_row = row; m_line = line; } template<class T> Matrix<T>::Matrix(int row, int line, const vector<T> nums) { mat.resize(row, vector<T>(line, 0)); if (nums.size() != (row * line)) cerr << endl << "数据格式与矩阵元素个数不匹配!" << endl; int cur = 0; for (int i = 0;i < row;i++) for (int j = 0;j < line;j++) mat[i][j] = nums[cur++]; m_row = row; m_line = line; }
|
拷贝构造函数需传入矩阵类型参数
1 2 3 4 5 6
| template<class T> Matrix<T>::Matrix(const Matrix& m) { mat = m.mat; m_line = m.m_line; m_row = m.m_row; }
|
矩阵的输入输出
矩阵的打印
1 2 3 4 5 6 7 8 9 10 11 12
| template<class T> void Matrix<T>::MatPrint() { cout << "{" << endl; for (int i = 0;i<m_row;i++) { cout << "["; for (int j = 0;j < m_line-1;j++) cout << mat[i][j] << ","; cout << mat[i][m_line - 1]; cout << "]" << endl; } cout << "}" << endl; }
|
矩阵的文件写入操作
文件的写采用附加写的方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| template<class T> void Matrix<T>::MatWrite(string file_name) { ofstream fout; fout.open(file_name,ios::app); if (!fout.is_open()) cerr << endl<< "文件打开失败!" << endl; for (int i = 0;i < m_row;i++) { fout << "[ "; for (int j = 0;j < m_line - 1;j++) fout << mat[i][j] << ","; fout << mat[i][m_line - 1]; fout << " ]" << endl; } fout.close(); }
|
矩阵的运算
±运算符的重载
矩阵的加减运算符的重载类似。
第一步首先要判断两个矩阵的维度是否一致,在一致的前提下才能进行加减法。
1 2 3 4 5 6 7 8 9 10 11 12
| template<class T> Matrix<T> Matrix<T>::operator+(const Matrix<T>& matrix) { if (this->m_line != matrix.getLine() || this->m_row != matrix.getRow()) { cerr << endl << "无法相加!" << endl; return Matrix(0,0); } Matrix tmp(this->m_row, this->m_line); for (int i = 0;i < this->m_row;i++) for (int j = 0;j < this->m_line;j++) tmp.mat[i][j] = this->mat[i][j] + matrix.mat[i][j]; return tmp; };
|
1 2 3 4 5 6 7 8 9 10 11 12
| template<class T> Matrix<T> Matrix<T>::operator-(const Matrix<T>& matrix) { if (this->m_line != matrix.getLine() || this->m_row != matrix.getRow()) { cerr << endl << "无法相减!" << endl; return Matrix(0, 0); } Matrix tmp(this->m_row, this->m_line); for (int i = 0;i < this->m_row;i++) for (int j = 0;j < this->m_line;j++) tmp.mat[i][j] = this->mat[i][j] - matrix.mat[i][j]; return tmp; };
|
*运算符的重载
矩阵的乘法规则不再详述。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| template<class T> Matrix<T> Matrix<T>::operator*(const Matrix<T>& matrix) { int row = this->m_row; int line = matrix.m_line; if (this->m_line != matrix.m_row){ cerr << endl << "无法相乘!" << endl; return Matrix(0, 0); } Matrix tmp(row,line); for (int i = 0;i < this->m_row;i++) for (int j = 0;j < line;j++) for (int k = 0;k < line;k++) tmp.mat[i][j] += this->mat[i][k] * matrix.mat[k][j]; return tmp; };
|
=运算符的重载
如果要实现类似a=b=c
这种连等形式的表达式时,重载的赋值运算符的返回值可以用引用形式。
1 2 3 4 5 6 7 8 9 10 11
| int temp; int fun1() { temp = 10; return temp; } int& fun2() { temp = 10; return temp; }
|
返回引用实际返回的是一个指向返回值的隐式指针,在内存中不会产生副本,是直接将temp拷贝给a,这样就避免产生临时变量,相比返回普通类型的执行效率更高,而且这个返回引用的函数也可以作为赋值运算符的左操作数。
下述代码为矩阵的赋值运算符的重载函数
1 2 3 4 5 6 7
| template<class T> Matrix<T>& Matrix<T>::operator=(const Matrix<T>& m) { mat = m.mat; m_line = m.m_line; m_row = m.m_row; return *this; };
|