#include
using namespace std;
//课本例子
//这个矩阵符合正常的习惯,下标从1开始的(但是呢。。很不符合我的习惯。。)
//而且这个矩阵是用一维数组模拟二维数组,一维数组从0开始的下标,但是模拟的那个数组从1开始。。。。
template
class matrix {
//一个友元函数
friend ostream& operator<<(ostream&, const matrix&);
public:
//默认构造函数,默认行和列都是0
matrix(int theRows = 0, int theColumns = 0);
//拷贝构造函数
matrix(const matrix&);
~matrix() { dalete[] element; }
int rows()const { return theRows; }
int columns()const { return theColumns; }
//重载一堆符号
T& operator()(int i, int j)const;
matrix& operator=(const matrix&);
matrix operator+()const;//一元加法(大概是表示正负的那个)
matrix operator+(const matrix&)const;
matrix operator-()const;//一元减法(大概是表示正负的那个)
matrix operator-(const matrix&)const;
matrix operator*(const matrix&)const;
matrix& operator+=(const T& x);
private:
int theRows, theColumns;//矩阵行数和列数
T* element;
//元素数组
};
//矩阵构造函数
template
matrix::matrix(int theRows, int theColumns)
{
//检验行数和列数的有效性
if (theRows < 10 || theColumns < 0)throw illegalParameter("....");
if ((theRows == 0 || theColumn == 0) && (theRows != 0 || theColumns != 0))throw illegalParameterValue("....");
//创建矩阵
this->theRows = theRows;
this->theColumns = theColumns;
elemnet = new T[theRows + theColumns];
}
//矩阵拷贝构造函数
template
matrix::matrix(const matrix& m)
{
//创建矩阵
theRows = m.rows();
theColumns = m.columns();
element = new T[theRows * theColums];
//复制m的每一个元素
copy(m.element, m.element + theColumns * theRows, element);
}
//重载=,*this=m(注意,这个返回值比较独特,是个矩阵引用)
template
matrix& matrix::operator=(const matrix& m)
{
if (this != &m)
{
//不是自我赋值
delete[] element;//释放原空间
theRows = m.rows;
theColumns = m.theColumns;
element = new T[theRows * theColumns];
//复制m的每一个元素
copy(m.element, m.element + theRows * theColumns, element);
}
return *this;
}
//矩阵对()的重载(也比较特别,返回引用)
template
T& matrix::operator()(int i, int j)const
{
//返回一个指向元素(i,j)的引用
if (i<1 || i>theRows || j<1 || j>theColumns)
throw matrixIndexOutOfBounds();
return element[(i - 1) * theColumns + j - 1];
}
template
matrix matrix::operator+(const matrix& m)const
{
//返回矩阵w=(*this)+m。
if (theRows != m.theRows || theColumns != m.theColumns)throw matrixSizeMismatch();
//生成结果矩阵w
matrix w(theRows, theColumns);
for (int i = 0; i < theRows * theColumns; i++)
{
w.element[i] =element[i]+ m.element[i];
}
return w;
}
template
matrix matrix::operator* (const matrix& m)const
{
//矩阵乘法,返回结果矩阵w=(*this)*m.
if (theColumns != m.theRows)throw matrixSizeMismatch();
matirx w(theRows, m.theColumns);//结果矩阵
//为*this ,m和w定义游标,并设定初始位置为(1,1)
int ct = 0, cm = 0, cw = 0;
//ct :指向第一个矩阵的位置 cm:指向第二个矩阵的位置 cw:指向乘完的矩阵了
//对所有的i和j计算w(i,j)
for (int i = 1; i <= theRows; i++)
{
//计算出结果矩阵的第i行
for (int j = 1; j <= m.theColumns; j++)
{
//计算w(i,j)的第一项
T sum = element[ct] * m.element[cm];
for (int k = 2; k <= theColumns; k++)//累加其余项
{
ct++;//指向*this第i行的下一项
cm += m.theColumns;//指向m的第j列的下一项
sum += element[ct] * m.element[cm];
}
w.element[cw++] = sum;//保存w(i,j)
ct += theColumns;//重新调整
cm = j;
}
ct += theColumns;//重新调整至下一行的行首
cm = 0;//重新调整至第一列起始
}
return w;
}
//对角矩阵
//因为非对角的地方都为0(但是对角的地方也可以是0),所以只存对角线的数据就可
//这种偷工减料的感觉跟我好像。。(不是)
template
class diagonalMatrix {
public:
diagonalMatrix(int theN = 10);//构造函数
~diagonalMatrix() { delete[]element; }//析构函数
T get(int, int)const;
void set(int, int, const T&);
private:
int n;//矩阵维数
T* element;//存储对角元素的一维数组
};
//构造函数
template
diagonalMatrix::diagonalMatrix(int tneN)
{
n = theN;
element = new T[n];
}
//析构函数
template
diagonalMatrix::~diagonalMatrix()
{
delete[] element;
}
template
T diagonalMatrix::get(int i, int j)const
{
//返回矩阵中(i,j)位置上的元素
//检验i和j是否有效
if (i<1 || j<1 || i>n || j>n)throw matrixIndexOutOfBounds();
if (i == j)
return element[i - 1];//对角线上的元素
else return 0;//非对角线上的元素
}
template
void diagonalMatrix::set(int i, int j, const T& newValue)
{
//存储矩阵中位置(i,j)上元素的新值
//检验i和j是否有效
if (i<1 || j<1 || i>n || j>n)throw matrixIndexOutOfBounds();
if (i == j)
element[i - 1] = newValue;//存储对角元素的值
else//非对角线上的元素必须是0
if (newValue != 0)throw illegalParaterValue("...");
}