编写了一个简单的矩阵类,可以实现矩阵的加减乘运算和求行列式等等

摘要

因为很久没有写过什么代码,于是打算写一个矩阵类来练一下手,找找感觉。
这次写的是一个简单的矩阵类,这个类里面的包含一个二维数组形式的成员用来存放矩阵,并且可以实现一些矩阵的基本运算,如加法、减法、乘法和赋值等等。(写的比较简陋,凑合着看吧)

Matrix类的构成

  • 数据成员
  1. int row 行
  2. int column 列
  3. long matrix** 动态二维数组
  • 成员函数
  1. Matrix(int r,int c) 构造函数,可以构造一个r行c列的矩阵
  2. void Random() 给矩阵生成随机数值
  3. int getRow() 返回矩阵的行数
  4. int getColumn() 返回矩阵的列数
  5. bool isSquare() 判断是否是方阵
  6. Matrix& operator =(...) 重载赋值运算符
  • 友元函数
  1. ostream & operator<<(...) 重载流提取运算符
  2. isteream & operator>>(...)重载流插入运算符
  3. Matrix operator +(...) 重载加号运算符
  4. Matrix operator -(...) 重载减号运算符
  5. Matrix operator *(...) 重载乘号运算符
  6. Matrix Minor(...) 求i,j元素的余子式
  7. bool canAdd(...) 检查是否可加
  8. bool canMul(...) 检查是否可乘
  9. 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<I&&j>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();
	}
}
posted @ 2019-07-05 22:31  裏表異体  阅读(2032)  评论(3编辑  收藏  举报