/***設(shè)計一個矩陣(摸板)類Matrix,實現(xiàn)矩陣的輸入和輸出(重載>>和<<),重載拷貝構(gòu)造函數(shù),
賦值運算和函數(shù)調(diào)用運算符()實現(xiàn)矩陣的轉(zhuǎn)置!、加、減、乘和求負(fù)-,必須處理各種異常
(越界、下標(biāo)錯誤、不匹配等)然后編寫主函數(shù)進(jìn)行全面的測試。*********************/
/****************************************************************************************************/
#include<iostream>
#include <conio.h> //getch原型
using namespace std;
//空間申請異常類
class Wrongmem{};
//下標(biāo)越界異常類
class Outofrange{};
//定義錯誤異常類
class Differ{};
/*********************************矩陣類開始**************************************/
const int MAX_SIZE=1000;
template<class T>
class Matrix
{
public:
//兩參數(shù)構(gòu)造函數(shù)
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();
}
//四參數(shù)構(gòu)造函數(shù)
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];
}
//析構(gòu)函數(shù)
~Matrix(){delete [] mem;}
T setrows()const{return rows;}
T setcols()const{return cols;}
//修改矩陣
void setMatrix(T *data,int size);
void setMatrix(T *data);
//重載函數(shù)調(diào)用運算符()
T &operator()(int i,int j);
//拷貝構(gòu)造函數(shù)
Matrix(const Matrix<T> &x);
//重載賦值運算符
Matrix<T> operator=(Matrix<T> &x);
//重載轉(zhuǎn)置!
Matrix<T> operator!();
//重載+
Matrix<T> operator+(const Matrix<T> &x);
//重載-
Matrix<T> operator-(const Matrix<T> &x);
//重載*
Matrix<T> operator*(const Matrix<T> &x);
//重載求負(fù)-
Matrix<T> operator-();
private:
T *mem;
const int rows,cols;
};
/**************************函數(shù)實現(xiàn)**********************************/
//修改矩陣
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];
}
//重載函數(shù)調(diào)用運算符()
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;
}
//拷貝構(gòu)造函數(shù)
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;
}
//重載轉(zhuǎn)置!
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;
}
//重載求負(fù)-
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;
}
/**************************主函數(shù)開始***************************/
void main()
{
try {
//矩陣的行和列必須在1和MAX_SIZE之間
Matrix<int> m0(0,3);
}
catch(...) {
cout<<"執(zhí)行語句Matrix<int> m0(0,3);導(dǎo)致矩陣的大小錯誤!\n";
}
try {
//矩陣的行和列必須在1和MAX_SIZE之間
Matrix<int> max(MAX_SIZE+1,3);
}
catch(...) {
cout<<"執(zhí)行語句Matrix<int> max("<<MAX_SIZE+1
<<",3);導(dǎo)致矩陣的大小錯誤!\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;
//利用拷貝構(gòu)造函數(shù)構(gòu)造矩陣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,并用數(shù)組a進(jìn)行初始化 **
** 等價于下述語句: **
** Matrix<int> m3(3,3,a,sizeof(a)/sizeof(int)); **
** 構(gòu)造函數(shù)的最后一個參數(shù)為數(shù)組的長度,默認(rèn)值為0 **
** 當(dāng)數(shù)組長度參數(shù)非0時將進(jìn)行數(shù)組長度和矩陣元素個數(shù)的匹配檢查! **
****************************************************************/
Matrix<int> m3(3,3,a);
cout<<"Matrix<int> m3(3,3,a):\n"<<m3;
m3=-m1; //求負(fù)(矩陣所有元素取相反值)
cout<<"Matrix m3=-m1:\n"<<m3;
m3=m1=m1; //與C++一樣允許連續(xù)賦值!
cout<<"Matrix m3=m1=m1:\n"<<m3;
cout<<endl;
cout<<"按任意鍵繼續(xù)......\n";
getch();
cout<<endl;
//矩陣轉(zhuǎn)置,等價于:m2=m1.transpose();
m2=!m1;
cout<<"Matrix m2=!m1:\n"<<m2;
m2.setMatrix(a); //用數(shù)組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<<"按任意鍵繼續(xù)......\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;
//允許元素個數(shù)不相同的矩陣進(jìn)行賦值!
//只要求目標(biāo)矩陣的容量足夠存放源矩陣的所有元素就允許賦值!
}
catch (...) {
cout<<"\n執(zhí)行語句m4=m3;導(dǎo)致矩陣的大小錯誤異常!\n\n";
//不允許元素個數(shù)不相同的矩陣進(jìn)行賦值時輸出該信息!
}
int b[]={0,1,2,3,4,5,6,7,8,9,9,8,7,6,5,4,3,2,1,0};
//用數(shù)組b修改矩陣m4各元素的值,同時進(jìn)行個數(shù)匹配檢查
m4.setMatrix(b,sizeof(b)/sizeof(int));
cout<<"m4.setMatrix(b,"<<sizeof(b)/sizeof(int)<<"):\n"<<m4;
//重載運算符!實現(xiàn)矩陣轉(zhuǎn)置,與成員函數(shù)transpose()功能一致!
m5=!m4;
cout<<"Matrix m5=!m4:\n"<<m5;
cout<<endl;
cout<<"按任意鍵繼續(xù)......\n";
getch();
cout<<endl;
cout<<"Matrix m5*m4:\n"<<m5*m4; //矩陣乘
cout<<"Matrix m4*m5:\n"<<m4*m5; //矩陣乘
cout<<endl;
try {
//第1個矩陣的列數(shù)不等于第2個矩陣的行數(shù)
cout<<m4*m4;
}
catch (...) {
cout<<"執(zhí)行語句cout<<m4*m4;導(dǎo)致矩陣的大小(不匹配)錯誤異常!\n";
}
try {
//超過矩陣m4的最大行、列數(shù)
for (i=0;i<=m4.setrows();++i)
for (int j=0;j<=m4.setcols();++j)
m4(i,j)=(i+1)*(j+1);
}
catch (...) {
cout<<"執(zhí)行上述程序段將導(dǎo)致下標(biāo)(訪問)越界異常!\n\n";
}
try {
//數(shù)組長度不足于給矩陣m4的所有元素賦值
m4.setMatrix(a,sizeof(a)/sizeof(int));
}
catch (...) {
cout<<"執(zhí)行語句m4.setMatrix(a,"<<sizeof(a)/sizeof(int)
<<");導(dǎo)致數(shù)組長度不足異常!\n";
}
try {
//雖然數(shù)組b有足夠的元素,但指定的長度小于矩陣m4的元素個數(shù)
m4.setMatrix(b,15);
}
catch (...) {
cout<<"執(zhí)行語句m4.setMatrix(b,15);導(dǎo)致數(shù)組長度不足異常!\n";
}
try {
//m3矩陣不足于存放矩陣m4的所有元素
m3=m4;
}
catch (...) {
cout<<"執(zhí)行語句m3=m4;導(dǎo)致矩陣的大小錯誤異常!\n";
}
try {
//第1個矩陣的列數(shù)必須等于第2個矩陣的行數(shù)才能相乘
m3=m1*m4;
}
catch (...) {
cout<<"執(zhí)行語句m3=m1*m4;導(dǎo)致矩陣的大小錯誤異常!\n";
}
try {
//兩個矩陣的行數(shù)和列數(shù)必須完全一致才能相加
m3=m4+m1;
}
catch (...) {
cout<<"執(zhí)行語句m3=m4+m1;導(dǎo)致矩陣的大小錯誤異常!\n";
}
try {
//兩個矩陣的行數(shù)和列數(shù)必須完全一致才能相減
m3=m4-m1;
}
catch (...) {
cout<<"執(zhí)行語句m3=m4-m1;導(dǎo)致矩陣的大小錯誤異常!\n";
}
cout<<endl;
}