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