摘要
因為很久沒有寫過什么代碼,於是打算寫一個矩陣類來練一下手,找找感覺。
這次寫的是一個簡單的矩陣類,這個類里面的包含一個二維數組形式的成員用來存放矩陣,並且可以實現一些矩陣的基本運算,如加法、減法、乘法和賦值等等。(寫的比較簡陋,湊合着看吧)
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<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();
}
}