1. 程式人生 > >矩陣類的實現,運算子過載

矩陣類的實現,運算子過載

技術含量不多,主要是自己收藏,記載著這裡,以後用的時候再看看。

//File matrix.h
#ifndef MATRIX_H
#define MATRIX_H

#include <iostream>
#include <string>
using namespace std;

template<typename T>
class Matrix
{
//private:
public:
	int row,col;                                      //行、列
	T *element;                                        //陣列
public:
	Matrix(int r = 1,int c = 1);                       //建構函式
	Matrix(int r, int c, T* initval);                  //建構函式
	Matrix(const Matrix<T>&);                          //拷貝建構函式
	~Matrix(){delete element;}                         //解構函式
	int Rowsize()const{return row;}                    //行長
	int Colsize()const{return col;}                    //列長
	T& operator()(int i,int j)const;                   //取元素
	Matrix<T>&operator=(const Matrix<T>&);             //賦值
	Matrix<T>operator+()const;                         //一元加
	Matrix<T>operator+(const Matrix<T>&);              //二元加
	Matrix<T>operator-()const;                         //一元減
	Matrix<T>operator-(const Matrix<T>&)const;         //二元減
	Matrix<T>operator*(const Matrix<T>&)const;         //乘法
	Matrix<T>transpose();                              //轉置
	friend ostream& operator<<(ostream& out, const Matrix<T>&);
};

//考慮到矩陣操作中可能出現異常,定義兩個異常類,分別表示下標越界和行、列不匹配的異常

class Bounds_error                                          //下標越界異常
{
public:
	Bounds_error(char* s):str(s){}
	void display()
	{cout<<str<<endl;}
private:
	string str;
};

class RCdismatch                                           //行列不匹配異常
{
public:
	RCdismatch(char* s):str(s){}
	void display()
	{cout<<str<<endl;}
private:
	string str;
};

#endif

//File Matrix.cpp  是類Matrix的實現檔案

#include <iomanip>
#include "matrix.h"
using namespace std;

//////////////////////////////////////////////////////////////
//各成員函式的實現
template<typename T>
Matrix<T>::Matrix(int r, int c)//建構函式
{
	row = r;
	col = c;
	element = new T[r*c];
}

//////////////////////////////
//測試的時候總是發現這個函式不對,除錯總是沒找出問題
///這是怎麼回事???怎麼回事??????
template<typename T>
Matrix<T>::Matrix(int r, int c, T* initval)//建構函式
{
	row = r;
	col = c;
	int size = r*c;
	element = new T[size];
	for (int i=0;i<size;i++)
		element[i] = *(initval + i);
}

template<typename T>
Matrix<T>::Matrix(const Matrix<T>& m)  //拷貝建構函式
{
	row = m.row;
	col = m.col;
	int size = row*col;
	element = new T[size];
	for (int i=0;i<size;i++)
		element[i] = m.element[i];
}


//圓括號()過載為舉證的下標操作,對下標i和j(0<=i<row,0<=j<col)
//輸出矩陣的第i行第j列元素,它在一維陣列中的位置是i*col+j
template<typename T>
T& Matrix<T>::operator()(int i,int j)const
{
	if(i < 0 || i > row - 1 || j < 0 || j > col - 1)
		throw Bounds_error("下標越界!");//異常
	return element[i*col+j];
}

//賦值運算子過載
template<typename T>
Matrix<T>& Matrix<T>::operator=(const Matrix<T>& m)
{
	if(row != m.row || col != m.col)
		throw RCdismatch("行、列不匹配,不能賦值!");
	int size = row * col;
	for(int i=0;i<size;i++)
		element[i]=m.element[i];
	return *this;
}

//一元加運算子過載
template<typename T>
Matrix<T> Matrix<T>::operator+()const
{

}

//二元加過載
template<typename T>
Matrix<T> Matrix<T>::operator+(const Matrix<T>& m)
{
	if(row != m.row || col != m.col)
		throw RCdismatch("行、列不匹配,不能賦值!");
	int size = row * col;
	for(int i=0;i<size;i++)
		element[i] += m.element[i];
	return this;
}

//一元減
template<typename T>
Matrix<T> Matrix<T>::operator-()const
{

}

//二元減
template<typename T>        
Matrix<T> Matrix<T>::operator-(const Matrix<T>& m)const
{
	if(row != m.row || col != m.col)
		throw RCdismatch("行、列不匹配,不能賦值!");
	int size = row * col;
	for(int i=0;i<size;i++)
		element[i] -= m.element[i];
	return this;
}

//乘法,矩陣(*this)乘以矩陣m
template<typename T>
Matrix<T> Matrix<T>::operator*(const Matrix<T>& m)const
{
	if(col != m.row)
		throw RCdismatch("行、列不匹配,不能賦值!");
	Matrix<T> w(row,m.col);
//	//這段是我自己寫的
// 	int sum,k;
// 	for (int i = 0; i < row; i ++)
// 	{
// 		for (int j = 0; j < m.col; j ++)
// 		{
// 			sum = 0;
// 			for (k = 0; k < col; k ++)
// 			{
// 				sum +=(*this)(i,k)*m(k,j);
// 			}
// 			w(i,j) = sum;
// 		}
// 	}
	int r = 0;
	for (int i = 0; i < row; i ++)
	{
		for (int j = 0; j < m.col; j ++)
		{
			int p = i * col;//矩陣*this第i行第一個元素的位置
			int q = j;//矩陣第j列第一個元素的位置
			T sum = element[p]*m.element[q];
			for (int k = 1; k < col; k ++)
			{
				p++;
				q+=m.col;
				sum+=element[p]*m.element[q];
			}
			w.element[r++] = sum;

		}
	}
	return w;
}

//轉置
template<typename T>
Matrix<T> Matrix<T>::transpose()
{
	Matrix<T>m(col,row);//矩陣m
	for(int i = 0; i < row; i ++)
	{
		for(int j = 0; j < col; j ++)
		{
			m(j,i) = (*this)(i,j);
		}
	}
	return m;
}

//輸出
template<typename T>
ostream& operator<<(ostream& out, const Matrix<T>& m)
{
	for (int i = 0; i < m.row; i ++)
	{
		for (int j = 0; j < m.col; j ++)
			cout << setw(5)<<m(i,j);
		cout<<endl;
	}
	return out;
}

//測試矩陣函式的程式
//#include "matrix.h"
#include "Matrix.cpp"
using namespace std;

int main()
{
	int data1[12] = {5,7,8,2,-2,4,1,1,1,2,3,4};
	int data2[20] = {4,-2,3,3,9,4,3,8,-1,2,2,3,5,2,7,1,0,6,3,4};
	Matrix<int> A(3,4,data1);
	Matrix<int> B(4,5,data2);
	cout<<A.transpose();
	cout<<"=============="<<endl;
	cout<<B.transpose();
	cout<<"=============="<<endl;
	try
	{
		cout<<A*B<<endl;
	}
	catch (RCdismatch& e)
	{
		e.display();
		cout<<endl;
	}
	catch (Bounds_error& e)
	{
		e.display();
		cout<<endl;
	}
	return 0;
}

除錯的時候發現建構函式總是不對,唉,怎麼都找不出問題。