C++实现对角矩阵(一维数组实现)


原理

当且仅当i不等于j时,M(i,j)=0为对角矩阵

一个rows X rows的对角矩阵D可以表示为一个二维数组element[rows][rows],其中element[i-1][j-1]表示D(i,j)。
这种表示法需要rows*rows个类型为T的数据空间。然而,对角矩阵对多只有rows个非0元素,因此可以用一维数组element[rows]来表示对角矩阵,其中elemennt[i-1]表示D(i,j).
所有未在一维数组中出现的矩阵元素均为0。这种表示法仅需要rows个类型为T的数据空间。

diagonalMatrix实现可对角矩阵转置输出加减乘除等操作。异常处理为自定义异常类型。不影响观看。可自己定义自己的异常类型。

此为《数据结构、算法与应用C++描述》书籍内容

diagonalMatrix.h

#include 
#include "myExceptions.h"

template
class diagonalMatrix
{
	friend std::ostream& operator<<
		(ostream& out, const diagonalMatrix& dm);
public:
	diagonalMatrix(int theN = 10);
	diagonalMatrix(const diagonalMatrix& dm);
	~diagonalMatrix() { delete[] element; }
	T get(int i, int j) const;
	void set(int i, int j, const T& newValue);

	diagonalMatrix tranpose();//转置矩阵
	diagonalMatrix& operator=(const diagonalMatrix& dm);

	diagonalMatrix operator+(const diagonalMatrix& dm) const;//二元正号
	diagonalMatrix operator-() const;//一元负号
	diagonalMatrix operator-(const diagonalMatrix& dm) const;//二元负号
	diagonalMatrix operator*(const diagonalMatrix& dm) const;

	diagonalMatrix& operator+=(const T& x);
	diagonalMatrix& operator-=(const T& x);
	diagonalMatrix& operator/=(const T& x);
	diagonalMatrix& operator*=(const T& x);
private:
	int n; //矩阵维数
	T* element;//存储对角矩阵的一维数组
};

template
diagonalMatrix::diagonalMatrix(int theN)
{//构造函数
	//检验theN值是否有效
	if (theN < 1)
		throw illegalParameterValue("Matrix size must be > 0");
	n = theN;
	element = new T[n];
}

template
diagonalMatrix::diagonalMatrix(const diagonalMatrix& dm)
{//赋值构造
	n = dm.n;
	element = new T[n];
	std::copy(dm.element, dm.element + n, element);
}

template
T diagonalMatrix::get(int i, int j) const
{//返回矩阵中(i,j)位置上的元素
	if (i<1 || j<1 || i>n || j>n)
		throw matrixIndexOutOfBounds();

	return (i == j) ? element[i - 1] : 0;
}

template
void diagonalMatrix::set(int i, int j, const T& newValue)
{//存储(i,j)项的新值
	if (i<1 || j<1 || i>n || j>n)
		throw matrixIndexOutOfBounds();

	if (i == j)
		element[i - 1] = newValue;
	else
		if (newValue != 0)
			throw illegalParameterValue("nondiagonal elements must be zero");
}

template
diagonalMatrix diagonalMatrix::tranpose()
{//转置矩阵,具体是修改本身矩阵还是返回值传递。。。
//看需求吧.例如可以是 void trandpose(diagonalMatrix& dm)
	diagonalMatrix w(n);
	for (int i = 0; i < n; ++i)
		w.element[i] = element[i];
	return w;
}

template
diagonalMatrix& diagonalMatrix::operator=(const diagonalMatrix& dm)
{//=号
	if(this !=&dm)
	{//是否=于了自己
		delete[] element;
		n = dm.n;
		element = new T[n];
		std::copy(dm.element, dm.element + n, element);
	}
	return *this;
}

template
diagonalMatrix diagonalMatrix::operator+(const diagonalMatrix& dm) const
{//二元加号
	if (n != dm.n)
		throw matrixSizeMismatch();
	diagonalMatrix w(n);
	for (int i = 0; i < n; ++i)
		w.element[i] = element[i] + dm.element[i];
	return w;
}

template
diagonalMatrix diagonalMatrix::operator-() const
{//一元负号
	diagonalMatrix w(n);
	for (int i = 0; i < n; ++i)
		w.element[i] = -element[i];
	return w;
}

template
diagonalMatrix diagonalMatrix::operator-(const diagonalMatrix& dm) const
{//二元负号
	if (n != dm.n)
		throw matrixSizeMismatch();
	diagonalMatrix w(n);
	for (int i = 0; i < n; ++i)
		w.element[i] = element[i] - dm.element[i];
	return w;
}

template
diagonalMatrix diagonalMatrix::operator*(const diagonalMatrix& dm) const
{//乘法
	if (n != dm.n)
		throw matrixSizeMismatch();
	diagonalMatrix w(n);
	for (int i = 0; i < n; ++i)
		w.element[i] = element[i] * dm.element[i];
	return w;
}

template
diagonalMatrix& diagonalMatrix::operator+=(const T& x)
{//+=
	for (int i = 0; i < n; ++i)
		element[i] += x;
	return *this;
}

template
diagonalMatrix& diagonalMatrix::operator-=(const T& x)
{//-=
	for (int i = 0; i < n; ++i)
		element[i] -= x;
	return *this;
}

template
diagonalMatrix& diagonalMatrix::operator/=(const T& x)
{// /=
	for (int i = 0; i < n; ++i)
		element[i] /= x;
	return *this;
}

template
diagonalMatrix& diagonalMatrix::operator*=(const T& x)
{//*=
	for (int i = 0; i < n; ++i)
		element[i] *= x;
	return *this;
}

template
std::ostream& operator<<
	(ostream& out, const diagonalMatrix& dm)
{//输出
	for (int i = 0; i < dm.n; i++)
	{
		for (int j = 0; j < dm.n; j++)
			if (i == j)
				out << dm.element[i] << " ";
			else
				out << 0 << " ";
		out << endl;
	}
	return out;
}

std::ostream& operator<<
	(ostream& out, const diagonalMatrix& dm)
{//出于某些原因,编译器不能自己创建这个。书上这么介绍的。不书写的话会出现一个链接错误。暂时没有找到原因
	for (int i = 0; i < dm.n; i++)
	{
		for (int j = 0; j < dm.n; j++)
			if (i == j)
				out << dm.element[i] << " ";
			else
				out << 0 << " ";
		out << endl;
	}
	return out;
}