摘要
因为很久没有写过什么代码,于是打算写一个矩阵类来练一下手,找找感觉。
这次写的是一个简单的矩阵类,这个类里面的包含一个二维数组形式的成员用来存放矩阵,并且可以实现一些矩阵的基本运算,如加法、减法、乘法和赋值等等。(写的比较简陋,凑合着看吧)Matrix类的构成
- 数据成员
- int row 行
- int column 列
- long matrix** 动态二维数组
- 成员函数
- Matrix(int r,int c) 构造函数,可以构造一个r行c列的矩阵
- void Random() 给矩阵生成随机数值
- int getRow() 返回矩阵的行数
- int getColumn() 返回矩阵的列数
- bool isSquare() 判断是否是方阵
- Matrix& operator =(...) 重载赋值运算符
- 友元函数
- ostream & operator<<(...) 重载流提取运算符
- isteream & operator>>(...)重载流插入运算符
- Matrix operator +(...) 重载加号运算符
- Matrix operator -(...) 重载减号运算符
- Matrix operator *(...) 重载乘号运算符
- Matrix Minor(...) 求i,j元素的余子式
- bool canAdd(...) 检查是否可加
- bool canMul(...) 检查是否可乘
long Determinant(...) 计算行列式的值
代码与算法
- Matrix类
- 这里声明了类的数据成员和各种函数的接口
class Matrix {public: Matrix(int m, int n); //构造函数,m行n列 friend ostream & operator << (ostream &, const Matrix &); //用友元重载流插入运算符,用于输出矩阵 friend istream & operator >> (istream &, Matrix &); //用友元重载流提取运算符,用于输入矩阵元素 friend Matrix operator + (const Matrix &, const Matrix &); //友元重载+运算符 friend Matrix operator - (const Matrix &, const Matrix &); //友元重载-运算符 friend Matrix operator * (const Matrix &, const Matrix &); //友元重载*运算符,实现矩阵乘法 Matrix& operator = (const Matrix & M); //成员函数重载赋值运算符 void Random(); //生成元素值是10以内的随机矩阵 friend Matrix Minor(const Matrix &,int I,int J); //求余子式 friend bool canAdd(const Matrix &,const Matrix &); //检查是否可加 friend bool canMul(const Matrix &, const Matrix &); //检查是否可乘 bool isSquare()const; //检查是否方阵 friend long Determinant(const Matrix &); //计算行列式的值 int getRow()const; //这里要用const约束,因为下面的operator的参数用了const限制 int getColumn()const;private: int row; //行 int column; //列 long ** matrix; //指向矩阵的二维数组};
- 构造函数
- 这里使用了二级指针来创建动态的二维数组。具体做法是先用二级指针指向一级指针,再用一级指针指向一维数组。
Matrix::Matrix(int m, int n) { row = m; column = n; matrix = new long*[row]; //指向一级指针数组 for (int i = 0; i < row; i++) { matrix[i] = new long[column]; //指向一维数组 }}
- 返回行数与列数
int Matrix::getRow()const { return row;}int Matrix::getColumn()const { return column;}
- 判断函数
- 判断两个矩阵是否可以进行加法运算
bool canAdd(const Matrix & L, const Matrix & R) { if (L.row == R.row&&L.column == R.column) { return true; } else { return false; }}
- 判断两矩阵是否可以进行乘法运算
bool canMul(const Matrix & L, const Matrix & R) { if (L.column == R.row) { //判断啊列数与行数是否相等 return true; } else { return false; }}
- 判断是否为方阵
bool Matrix::isSquare()const { if (row == column) { return true; } else { return false; }}
- 为矩阵生成随机数值的函数
void Matrix::Random() { for (int i = 0; i < row; i++) { for (int j = 0; j < column; j++) { matrix[i][j] = rand() % 10; //用了随机函数,生成0-1之内的数值 } }}
- 计算某个元素的余子式
Matrix Minor(const Matrix & M,int I,int J) { //求[I,J]元素的余子式 if (M.isSquare()) { //判断是否为方阵 int r = M.getColumn() - 1; //余子式的阶数 Matrix minor(r, r); for (int i = 0; i < M.getRow(); i++) { if (i == I) { //除去第I行 continue; } for (int j = 0; j < M.getColumn(); j++) { if (j == J) { //除去第J列 continue; } if (i > I&&j > J) { minor.matrix[i - 1][j - 1] = M.matrix[i][j]; } else if (i > I&&j < J) { minor.matrix[i - 1][j] = M.matrix[i][j]; } else if (i J) { minor.matrix[i][j - 1] = M.matrix[i][j]; } else { minor.matrix[i][j] = M.matrix[i][j]; } } } return minor; } else { cout << "不是方阵,无法求余子式!" << endl; abort(); }}
- 计算行列式的函数
- 这里通过对第一行元素进行拉普拉斯展开进行矩阵的行列式求值。因为用了递归算法,调用开销较大,本机上最多只能算到10阶矩阵的行列式。
long Determinant(const Matrix & M) { if(M.isSquare()) { //判断是否方阵 //用来存储计算结果 long det = 0; int count = M.getRow(); if (M.column == 2) { //终止条件 //long det = 0; det += M.matrix[0][0] * M.matrix[1][1] - M.matrix[0][1] * M.matrix[1][0]; } else { //递归 for (int i = 0; i < M.column; i++) { //按第一行展开 //long det = 0; int n = M.column - 1; if (((i+3) % 2)) { //判断是加还是减 det += M.matrix[0][i]*Determinant(Minor(M,0,i)); //递归调用 } else { det -= M.matrix[0][i]*Determinant(Minor(M, 0, i)); //递归调用 } count--; } } return det; } cout << "无法求行列式!" << endl; abort();}
- 实现矩阵加法的函数
Matrix operator + (const Matrix & L, const Matrix & R){ if (canAdd(L, R)) { Matrix temp(L.row, L.column); //创建临时对象 for (int i = 0; i < L.row; i++) { for (int j = 0; j < L.column; j++) { temp.matrix[i][j] = L.matrix[i][j] + R.matrix[i][j]; } } return temp; } else { cout << "矩阵不同形,无法相加" << endl; abort(); }}
- 实现矩阵减法的函数
Matrix operator - (const Matrix & L, const Matrix & R) { if (canAdd(L, R)) { Matrix temp(L.row, L.column); //创建临时对象 for (int i = 0; i < L.row; i++) { for (int j = 0; j < L.column; j++) { temp.matrix[i][j] = -(L.matrix[i][j] + R.matrix[i][j]); } } return temp; } else { cout << "矩阵不同形,无法相减!" << endl; abort(); }}
- 实现矩阵乘法的函数
- 矩阵的乘法也就是左边矩阵的第i行与右边矩阵的第j列进行数量积运算,得到的值作为新矩阵的第i,j个元素,所以用了三个循环进行遍历,第一个是左矩阵的行,第二个是右矩阵的列,第三个是左边的列与右边的行(乘法要求左矩阵的列数要与右矩阵的行数相同)
Matrix operator * (const Matrix & L, const Matrix & R) { if (canMul(L, R)) { //判断是否合法 Matrix temp(L.row, R.column); //创建一个m行n列的矩阵,行数与L相等,列数与R相等 for (int i = 0; i < L.row; i++) { for (int j = 0; j < R.column; j++) { long sum=0; for (int k = 0; k < L.column; k++) { sum += L.matrix[i][k] * R.matrix[k][j]; //累加第i行与第j列的元素乘积 } temp.matrix[i][j] = sum; //赋给i,j元素 } } return temp; } else { cout << "矩阵无法进行乘法运算!" << endl; abort(); }}