矩阵类 -- tigerwood -- 编程爱好者博客/***设计一个矩阵(摸板)类Matrix,实现矩阵的输入和输出(重载>>和<<),重载拷贝构造函数,
赋值运算和函数调用运算符()实现矩阵的转置!、加、减、乘和求负-,必须处理各种异常 (越界、下标错误、不匹配等)然后编写主函数进行全面的测试。*********************/ /****************************************************************************************************/ #include<iostream> #include <conio.h> //getch原型 using namespace std; //空间申请异常类 class Wrongmem{}; //下标越界异常类 class Outofrange{}; //定义错误异常类 class Differ{}; /*********************************矩阵类开始**************************************/ const int MAX_SIZE=1000; template<class T> class Matrix { public: //两参数构造函数 Matrix(int r,int c):rows(r),cols(c) { if(rows>MAX_SIZE||rows<1||cols>MAX_SIZE||cols<1) throw Outofrange(); mem=new T [rows*cols]; if(mem==NULL) throw Outofrange(); } //四参数构造函数 Matrix(int r,int c,T *data,int size=0):rows(r),cols(c) { if(rows>MAX_SIZE||rows<1||cols>MAX_SIZE||cols<1) throw Outofrange(); if(size && size<sizeof(rows*cols)/sizeof(int)) throw Outofrange(); mem=new T [rows*cols]; if(mem==NULL) throw Wrongmem(); for(int i=0;i<rows*cols;i++) mem[i]=data[i]; } //析构函数 ~Matrix(){delete [] mem;} T setrows()const{return rows;} T setcols()const{return cols;} //修改矩阵 void setMatrix(T *data,int size); void setMatrix(T *data); //重载函数调用运算符() T &operator()(int i,int j); //拷贝构造函数 Matrix(const Matrix<T> &x); //重载赋值运算符 Matrix<T> operator=(Matrix<T> &x); //重载转置! Matrix<T> operator!(); //重载+ Matrix<T> operator+(const Matrix<T> &x); //重载- Matrix<T> operator-(const Matrix<T> &x); //重载* Matrix<T> operator*(const Matrix<T> &x); //重载求负- Matrix<T> operator-(); private: T *mem; const int rows,cols; }; /**************************函数实现**********************************/ //修改矩阵 template <class T> void Matrix<T>::setMatrix(T *data,int size) { if(rows*cols>size) throw Outofrange(); for(int i=0;i<size;i++) mem[i]=data[i]; } template<class T> void Matrix<T>::setMatrix(T *data) { for(int i=0;i<rows*cols;i++) mem[i]=data[i]; } //重载函数调用运算符() template <class T> T &Matrix<T>::operator()(int i,int j) { if(i>=rows||j>=cols) throw Outofrange(); else return mem[i*cols+j]; } //重载输入运算符 template<class T> istream &operator >> (istream &in,Matrix<T> &x) { for(int i=0;i<x.setrows();i++) { for(int j=0;j<x.setcols();j++) in>>x(i,j); } return in; } //重载输出<< template <class T> ostream &operator<<(ostream &out,Matrix<T> &x) { for(int i=0;i<x.setrows();i++) { for(int j=0;j<x.setcols();j++) out<<x(i,j)<<' '; out<<endl; } out<<endl; return out; } //拷贝构造函数 template <class T> Matrix<T>::Matrix(const Matrix<T> &x):rows(x.rows),cols(x.cols) { mem=new T [rows*cols]; if(mem==NULL) throw Differ(); else for(int i=0;i<x.rows*x.cols;i++) mem[i]=x.mem[i]; } //重载附值运算符= template <class T> Matrix<T> Matrix<T>::operator=(Matrix<T> &x) { if(rows!=x.rows||cols!=x.cols)throw Differ(); if(this!=&x) { delete [] mem; mem=new T [rows*cols]; if(mem==NULL) throw Wrongmem(); else for(int i=0;i<x.rows*x.cols;i++) mem[i]=x.mem[i]; } return *this; } //重载转置! template <class T> Matrix<T> Matrix<T>::operator!() { Matrix<T> temp(cols,rows); for(int i=0;i<cols;i++) for(int j=0;j<rows;j++) temp(i,j)=(*this)(j,i); return temp; } //重载+ template <class T> Matrix<T> Matrix<T>::operator+(const Matrix<T> &x) { int i; if(rows!=x.rows||cols!=x.cols)throw Differ(); Matrix<T> temp(*this); if(rows==x.rows&&cols==x.cols) { for(i=0;i<rows*cols;i++) temp.mem[i]=mem[i]+x.mem[i]; return temp; } else throw Differ(); } //重载- template <class T> Matrix<T> Matrix<T>::operator-(const Matrix<T> &x) { int i; if(rows!=x.rows||cols!=x.cols)throw Differ(); Matrix<T> temp(*this); if(rows==x.rows&&cols==x.cols) { for(i=0;i<rows*cols;i++) temp.mem[i]=mem[i]-x.mem[i]; return temp; } else throw Differ(); } //重载矩阵乘法运算符* template<class T> Matrix<T> Matrix<T>::operator*(const Matrix<T> &x) { if(cols!=x.rows) throw Differ(); Matrix<T> temp(rows,x.cols); for(int i=0;i<rows;i++) for(int j=0;j<x.cols;j++) { temp(i,j)=0; for(int k=0;k<x.rows;k++) temp(i,j)+=mem[i*cols+k]*x.mem[k*x.cols+j]; } return temp; } //重载求负- template<class T> Matrix<T> Matrix<T>::operator-() { Matrix<T> temp(*this); for(int i=0;i<rows*cols;i++) temp.mem[i]=(-1)*mem[i]; return temp; } /**************************主函数开始***************************/ void main() { try { //矩阵的行和列必须在1和MAX_SIZE之间 Matrix<int> m0(0,3); } catch(...) { cout<<"执行语句Matrix<int> m0(0,3);导致矩阵的大小错误!\n"; } try { //矩阵的行和列必须在1和MAX_SIZE之间 Matrix<int> max(MAX_SIZE+1,3); } catch(...) { cout<<"执行语句Matrix<int> max("<<MAX_SIZE+1 <<",3);导致矩阵的大小错误!\n"; } cout<<endl; //定义3行3列的空矩阵m1 Matrix<int> m1(3,3); cout<<"Input Matrix m1(3,3):\n"; //利用已重载的输入运算符>>输入矩阵 cin>>m1; //利用已重载的输出运算符<<输出矩阵 cout<<"Matrix m1(3,3):\n"<<m1; //利用拷贝构造函数构造矩阵m2(3行3列) Matrix<int> m2(m1); cout<<"Matrix m2(m1):\n"<<m2; int a[]={9,8,7,6,5,4,3,2,1}; /**************************************************************** ** 定义3行3列的空矩阵m3,并用数组a进行初始化 ** ** 等价于下述语句: ** ** Matrix<int> m3(3,3,a,sizeof(a)/sizeof(int)); ** ** 构造函数的最后一个参数为数组的长度,默认值为0 ** ** 当数组长度参数非0时将进行数组长度和矩阵元素个数的匹配检查! ** ****************************************************************/ Matrix<int> m3(3,3,a); cout<<"Matrix<int> m3(3,3,a):\n"<<m3; m3=-m1; //求负(矩阵所有元素取相反值) cout<<"Matrix m3=-m1:\n"<<m3; m3=m1=m1; //与C++一样允许连续赋值! cout<<"Matrix m3=m1=m1:\n"<<m3; cout<<endl; cout<<"按任意键继续......\n"; getch(); cout<<endl; //矩阵转置,等价于:m2=m1.transpose(); m2=!m1; cout<<"Matrix m2=!m1:\n"<<m2; m2.setMatrix(a); //用数组a修改矩阵m2各元素的值 cout<<"Matrix m2.setMatrix(a):\n"<<m2; m2=m1+m1; //矩阵加 cout<<"Matrix m2=m1+m1:\n"<<m2; m3=m1*m2; //矩阵乘 cout<<"Matrix m3=m1*m2:\n"<<m3; m3=m3-m2; //矩阵减 cout<<"Matrix m3=m3-m2:\n"<<m3; cout<<endl; cout<<"按任意键继续......\n"; getch(); cout<<endl; Matrix<int> m4(4,5),m5(5,4); //利用已重载的运算符()直接给矩阵m4赋值 for (int i=0;i<m4.setrows();++i) for (int j=0;j<m4.setcols();++j) m4(i,j)=(i+1)*(j+1); cout<<"Matrix m4:\n"<<m4; try { //m4矩阵空间大于存放矩阵m3所有元素的空间 m4=m3; cout<<"Matrix m4=m3:\n"<<m4; //允许元素个数不相同的矩阵进行赋值! //只要求目标矩阵的容量足够存放源矩阵的所有元素就允许赋值! } catch (...) { cout<<"\n执行语句m4=m3;导致矩阵的大小错误异常!\n\n"; //不允许元素个数不相同的矩阵进行赋值时输出该信息! } int b[]={0,1,2,3,4,5,6,7,8,9,9,8,7,6,5,4,3,2,1,0}; //用数组b修改矩阵m4各元素的值,同时进行个数匹配检查 m4.setMatrix(b,sizeof(b)/sizeof(int)); cout<<"m4.setMatrix(b,"<<sizeof(b)/sizeof(int)<<"):\n"<<m4; //重载运算符!实现矩阵转置,与成员函数transpose()功能一致! m5=!m4; cout<<"Matrix m5=!m4:\n"<<m5; cout<<endl; cout<<"按任意键继续......\n"; getch(); cout<<endl; cout<<"Matrix m5*m4:\n"<<m5*m4; //矩阵乘 cout<<"Matrix m4*m5:\n"<<m4*m5; //矩阵乘 cout<<endl; try { //第1个矩阵的列数不等于第2个矩阵的行数 cout<<m4*m4; } catch (...) { cout<<"执行语句cout<<m4*m4;导致矩阵的大小(不匹配)错误异常!\n"; } try { //超过矩阵m4的最大行、列数 for (i=0;i<=m4.setrows();++i) for (int j=0;j<=m4.setcols();++j) m4(i,j)=(i+1)*(j+1); } catch (...) { cout<<"执行上述程序段将导致下标(访问)越界异常!\n\n"; } try { //数组长度不足于给矩阵m4的所有元素赋值 m4.setMatrix(a,sizeof(a)/sizeof(int)); } catch (...) { cout<<"执行语句m4.setMatrix(a,"<<sizeof(a)/sizeof(int) <<");导致数组长度不足异常!\n"; } try { //虽然数组b有足够的元素,但指定的长度小于矩阵m4的元素个数 m4.setMatrix(b,15); } catch (...) { cout<<"执行语句m4.setMatrix(b,15);导致数组长度不足异常!\n"; } try { //m3矩阵不足于存放矩阵m4的所有元素 m3=m4; } catch (...) { cout<<"执行语句m3=m4;导致矩阵的大小错误异常!\n"; } try { //第1个矩阵的列数必须等于第2个矩阵的行数才能相乘 m3=m1*m4; } catch (...) { cout<<"执行语句m3=m1*m4;导致矩阵的大小错误异常!\n"; } try { //两个矩阵的行数和列数必须完全一致才能相加 m3=m4+m1; } catch (...) { cout<<"执行语句m3=m4+m1;导致矩阵的大小错误异常!\n"; } try { //两个矩阵的行数和列数必须完全一致才能相减 m3=m4-m1; } catch (...) { cout<<"执行语句m3=m4-m1;导致矩阵的大小错误异常!\n"; } cout<<endl; } |
|