zoukankan      html  css  js  c++  java
  • 编写了一个简单的矩阵类,可以实现矩阵的加减乘运算和求行列式等等

    摘要

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

    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();
    	}
    }
    
  • 相关阅读:
    JAVA总结--正则表达式
    JAVA总结--java数据类型
    数据结构与算法
    JAVA总结--JDK版本区别
    JAVA总结--代码规范
    .net core 学习笔记(4)-ViewComponent
    .net core学习笔记(3)-依赖注入
    .net core 学习笔记(2)-中间件
    .net core 学习笔记(1)-分页控件的使用
    taginput ,complete使用笔记
  • 原文地址:https://www.cnblogs.com/urahyou/p/11141085.html
Copyright © 2011-2022 走看看