《数据结构、算法与应用C++语言描述》使用C++语言实现二维数组矩阵

《数据结构、算法与应用C++语言描述》使用C++语言实现二维数组矩阵

行主映射与列主映射

如图7-2所示。

行主映射:从第一行开始,依次对每一行的索引从左至右连续编号。

列主映射:对索引的编号从最左列开始,依次对每一列的索引从上到下连续编号。

《数据结构、算法与应用C++语言描述》使用C++语言实现二维数组矩阵_第1张图片

行主映射的映射函数:

在这里插入图片描述

列主映射的映射函数:
m a p ( i 1 , i 2 ) = i 2 u 1 + i 1 ( u 1 表示行数, u 2 表示列数 ) map(i_1, i_2) = i_2u_1+i_1(u_1表示行数,u_2表示列数) map(i1,i2)=i2u1+i1(u1表示行数,u2表示列数)

矩阵定义及运算

定义

一个mxn 的矩阵(matrix)是一个m 行、n 列的表(如图 7-4所示),m 和 n 是矩阵的维数(dimension)。

《数据结构、算法与应用C++语言描述》使用C++语言实现二维数组矩阵_第2张图片

矩阵运算

矩阵转置:一个mxn的矩阵M转置之后是一个nxm 的矩阵 M T M^T MT

在这里插入图片描述

矩阵相加:两个矩阵仅当维数相同时(即它们的行数和列数都分别相等)才可以相加。两个m×n的矩阵 A 和 B 相加之后是一个mxn 的矩阵C,如下所示:

在这里插入图片描述

矩阵相乘:一个mxn的矩阵A和一个qxp的矩阵B,只有当A的列数等于B的行数(即n=q)时,才可以相乘AB。AB的结果是一个mxp的矩阵C,它们的关系是:

在这里插入图片描述

代码实现

模板头文件:_8matrix.h

/*
Project name :			allAlgorithmsTest
Last modified Date:		2022年8月13日17点38分
Last Version:			V1.0
Descriptions:			数组存储的二维矩阵类头文件
*/
#pragma once
#ifndef _MATRIX_H_
#define _MATRIX_H_
#include "_1myExceptions.h"
#include
#include 
using namespace std;
//矩阵的测试cpp文件
void matrixTest();
/*行主描述的矩阵*/
template<class T>
class matrix
{
public:
	int rows() const { return theRows; }
	int columns() const { return theColumns; }
	matrix(int theRows, int theColumns);//已测
	matrix(const matrix<T>& m);//已测
	matrix<T>& operator=(const matrix<T>& m);//已测
	T& operator()(int i, int j) const;//已测
	matrix<T> operator+() const;//已测
	matrix<T> operator+(const matrix<T>& m) const;//已测
	matrix<T> operator+(const T& data) const;//已测
	matrix<T>& operator+=(const matrix<T>& m);//已测
	matrix<T>& operator+=(const T& data);//已测
	matrix<T> operator-() const;
	matrix<T> operator-(const matrix<T>& m) const;
	matrix<T> operator-(const T& data) const;
	matrix<T>& operator-=(const matrix<T>& m);
	matrix<T>& operator-=(const T& data);
	matrix<T> operator*(const matrix<T>& m) const;
	matrix<T> operator*(const T& data) const;
	matrix<T>& operator*=(const T& data);
	matrix<T> operator/(const T& data) const;
	matrix<T>& operator/=(const T& data);	
	matrix<T> tranpose();
	//<<和>>没有加之前一直报错LNK1120和LNK2019,加了之后就不报错了,我也不知道为什么
	//应该是一种实例化吧
	friend ostream& operator<< <T>(ostream& out, const matrix<T>& m);//已测
	friend istream& operator>> <T>(istream& in, const matrix<T>& m);//已测
private:
	int theRows;//矩阵的行数
	int theColumns;//矩阵的列数
	T* element;//数组element
};
/*友元函数:重载输出操作符*/
template<class T>
ostream& operator<<(ostream& out, const matrix<T>& m)
{
	int k = 0;
	for (int i = 0; i < m.theRows; i++)
	{
		cout << endl;
		for (int j = 0; j < m.theColumns; j++)
		{
			out.width(3);
			out << m.element[k++] << "  ";
		}			
	}
	return out;
}
/*友元函数:重载输入操作符*/
template<class T>
istream& operator>>(istream& in, const matrix<T>& m)
{
	cout << "请输入矩阵" << m.theRows << "*" << m.theColumns << ":" << endl;	
	for (int i = 0; i < (m.theRows) * (m.theColumns); i++)
	{
		cout << "Please enter a data: ";
		while (!(in >> m.element[i])) {//如果输入类型不匹配,则执行循环体
			in.clear(); // reset input设置标志位为有效
			while (in.get() != '\n') //删除没有用的输入
				continue; // get rid of bad input
			cout << "Please enter a data: ";
		}
	}
	return in;
}
/*构造函数*/
template<class T>
matrix<T>::matrix(int theRows, int theColumns)
{
	//检验行数和列数的有效性
	if (theRows < 0 || theColumns < 0)
		throw illegalParameterValue("Rows and columns mush be >=0");
	if((theRows==0||theColumns==0)&&(theRows!=0||theColumns!=0)) //要为0时行数和列数必须同时为0
		throw illegalParameterValue("Either both or neither rows and columns should be zero");
	//创建矩阵
	this->theRows = theRows;
	this->theColumns = theColumns;
	element = new T[theRows * theColumns];
}
/*复制构造函数*/
template<class T>
matrix<T>::matrix(const matrix<T>& m)
{
	//创建数组
	theRows = m.theRows;
	theColumns = m.theColumns;
	element = new T[theRows * theColumns];

	//复制m的每一个元素
	copy(m.element, m.element + theRows * theColumns, element);
}
/*矩阵转置*/
template<class T>
matrix<T> matrix<T>::tranpose()
{
	matrix<T> w(theColumns, theRows);
	for(int i = 1;i<=theRows;i++)
		for (int j = 1; j <= theColumns; j++)
		{
			w(j, i) = (*this)(i, j);
		}
	return w;
}

/*重载操作符*/
/*赋值操作符=的重载*/
template<class T>
matrix<T>& matrix<T>::operator=(const matrix<T>& m)
{
	if (this != &m)//不能自己复制自己
	{
		delete[] element;
		theRows = m.theRows;
		theColumns = m.theColumns;
		element = new T[theRows * theColumns];
		//复制m的每一个元素
		copy(m.element, m.element + theRows * theColumns, element);
	}
	return *this;
}
/*重载()操作符*/
template<class T>
T& matrix<T>::operator()(int i, int j) const
{
	if (i<1 || j<1 || i>theRows || j>theColumns)
		throw matrixIndexOutOfBounds();
	return element[(i - 1) * theColumns + j - 1];
}
/*重载一元+操作符*/
template<class T>
matrix<T> matrix<T>::operator+() const
{
	matrix<T> w(theRows, theColumns);
	for (int i = 0; i < theRows * theColumns; i++)
		w.element[i] = element[i];
	return w;
}
/*重载二元+操作符*/
template<class T>
matrix<T> matrix<T>::operator+(const matrix<T>& m) const
{
	if (theRows != m.theRows || theColumns != m.theColumns)
		throw matrixSizeMismatch();
	//生成结果矩阵
	matrix<T> w(theRows, theColumns);
	for (int i = 0; i < theRows * theColumns; i++)
		w.element[i] = element[i] + m.element[i];
	return w;
}
/*重载+操作符:让矩阵所有元素都加一个整数*/
template<class T>
matrix<T> matrix<T>::operator+(const T& data) const
{
	matrix<T> w(theRows, theColumns);
	for (int i = 0; i < theRows * theColumns; i++)
		w.element[i] = element[i] + data;
	return w;
}
/*重载+=操作符*/
/*当前矩阵加一个矩阵*/
template<class T>
matrix<T>& matrix<T>::operator+=(const matrix<T>& m)
{
	for (int i = 0; i < theRows * theColumns; i++)
		element[i] = element[i] + m.element[i];
	return *this;
}
/*重载+=操作符*/
/*当前矩阵每个元素加一个数*/
template<class T>
matrix<T>& matrix<T>::operator+=(const T& data)
{
	for (int i = 0; i < theRows * theColumns; i++)
		element[i] = element[i] + data;
	return *this;
}
/*重载一元-操作符*/
template<class T>
matrix<T> matrix<T>::operator-() const
{
	matrix<T> w(theRows, theColumns);
	for (int i = 0; i < theRows * theColumns; i++)
		w.element[i] = -element[i];
	return w;
}
/*重载二元-操作符:矩阵减矩阵*/
template<class T>
matrix<T> matrix<T>::operator-(const matrix<T>& m) const
{
	matrix<T> w(theRows, theColumns);
	for (int i = 0; i < theRows * theColumns; i++)
		w.element[i] = element[i] - m.element[i];
	return w;
}
/*重载二元-操作符:矩阵减数据*/
template<class T>
matrix<T> matrix<T>::operator-(const T& data) const
{
	matrix<T> w(theRows, theColumns);
	for (int i = 0; i < theRows * theColumns; i++)
		w.element[i] = element[i] - data;
	return w;
}
/*重载-=操作符:矩阵加一个矩阵*/
template<class T>
matrix<T>& matrix<T>::operator-=(const matrix<T>& m)
{
	for (int i = 0; i < theRows * theColumns; i++)
		element[i] = element[i] - m.element[i];
	return *this;
}
/*重载-=操作符:矩阵的每个元素加数data*/
template<class T>
matrix<T>& matrix<T>::operator-=(const T& data)
{
	for (int i = 0; i < theRows * theColumns; i++)
		element[i] = element[i] - data;
	return *this;
}
/*重载*操作符*/
template<class T>
matrix<T> matrix<T>::operator*(const matrix<T>& m) const
{
	if (theColumns != m.theRows)
		throw matrixSizeMismatch();
	matrix<T> w(theRows, m.theColumns);//结果矩阵
	int indext = 0, indexm = 0, indexw = 0;//三个矩阵的游标
	T multiData = 0;
	for (int i = 1; i <= theRows; i++)
	{
		for (int j = 1; j <= m.theColumns; j++)
		{
			multiData = element[indext] * element[indexm];
			for (int k = 2; k <= theColumns; k++)
			{
				indext++;
				indexm += m.theColumns;
				multiData += element[indext] * element[indexm];
			}
			w.element[indexw++] = multiData;
			//从行的起点和下一列从新开始
			indext -= (theColumns - 1);
			indexm = j;
		}
		//从下一行和下一列重新开始
		indext += theColumns;
		indexm = 0;
	}
	return w;
}
/*重载*操作符:矩阵乘以数据data*/
template<class T>
matrix<T> matrix<T>::operator*(const T& data) const
{
	matrix<T> w(theRows, theColumns);
	for (int i = 0; i < theRows * theColumns; i++)
		w.element[i] = element[i] * data;
	return w;
}
/*重载*=操作符:矩阵乘以矩阵,不好弄且没必要*/
/*重载*=操作符:矩阵乘以数据data*/
template<class T>
matrix<T>& matrix<T>::operator*=(const T& data)
{
	for (int i = 0; i < theRows * theColumns; i++)
		element[i] = element[i] * data;
	return *this;
}
/*重载/操作符*/
template<class T>
matrix<T> matrix<T>::operator/(const T& data) const
{
	matrix<T> w(theRows, theColumns);
	for (int i = 0; i < theRows * theColumns; i++)
		w.element[i] = element[i] / data;
	return w;
}
/*重载/=操作符*/
template<class T>
matrix<T>& matrix<T>::operator/=(const T& data)
{
	for (int i = 0; i < theRows * theColumns; i++)
		element[i] = element[i] / data;
	return *this;
}

#endif

cpp测试函数文件:_8matrix.cpp

/*
Project name :			allAlgorithmsTest
Last modified Date:		2022年8月13日17点38分
Last Version:			V1.0
Descriptions:			测试_8matrix.h头文件中的所有函数
*/
#include"_8matrix.h"
#include
using namespace std;

void matrixTest()
{
	cout << endl << "**********************************matrixTest()函数开始****************************************" << endl;
	cout << endl << "测试成员函数*******************************************" << endl;
	cout << "构造函数+输入输出***************" << endl;
	matrix<int> matrix1(2, 3);
	cin >> matrix1;
	cout <<"matrix1 = "<< matrix1 << endl;
	matrix<int> matrix2(matrix1);
	cout << "matrix2 = " << matrix2 << endl;
	cout << "测试tranpose()成员函数**********" << endl;
	matrix<int> matrix14 = matrix2.tranpose();
	cout << "matrix14 = " << matrix14 << endl;
	cout << endl << "重载操作符**********************************************" << endl;
	cout << "重载=操作符*********************" << endl;
	matrix<int> matrix3 = matrix2;
	cout << "matrix3 = " << matrix3 << endl;
	cout << "重载()操作符********************" << endl;
	cout << "matrix3(1,2) = " << matrix3(1,2) << endl;
	cout << "重载一元+操作符*****************" << endl;
	matrix<int> matrix4 = +matrix3;
	cout << "matrix4 = +matrix3:" << matrix4 << endl;
	cout << "重载二元+操作符:矩阵加矩阵*****" << endl;
	matrix<int> matrix5 = matrix3 + matrix4;
	cout << "matrix5 = matrix3 + matrix4:" << matrix5 << endl;
	cout << "重载二元+操作符:矩阵加数据*****" << endl;
	matrix<int> matrix6 = matrix5+2;
	cout << "matrix6 = matrix5+2:" << matrix6 << endl;
	cout << "重载+=操作符:矩阵加矩阵********" << endl;
	matrix6 += matrix5;
	cout << "matrix6 += matrix5:" << matrix6 << endl;
	cout << "重载+=操作符:矩阵加数据********" << endl;
	matrix6 += 1;
	cout << "matrix6 += 1:" << matrix6 << endl;
	cout << "重载一元-操作符*****************" << endl;
	matrix<int> matrix7 = -matrix6;
	cout << "matrix7 = -matrix6:" << matrix7 << endl;
	cout << "重载二元-操作符:矩阵减矩阵*****" << endl;
	matrix<int> matrix8 = matrix7 - matrix5;
	cout << "matrix8 = matrix7 - matrix5:" << matrix8 << endl;
	cout << "重载二元-操作符:矩阵减数据*****" << endl;
	matrix<int> matrix9 = matrix8 - 1;
	cout << "matrix9 = matrix8 - 1:" << matrix9 << endl;
	cout << "重载-=操作符:矩阵减矩阵********" << endl;
	matrix9 -= matrix8;
	cout << "matrix9 -= matrix8:" << matrix9 << endl;
	cout << "重载-=操作符:矩阵减数据********" << endl;
	matrix9 -= 2;
	cout << "matrix9 -= 2:" << matrix9 << endl;
	cout << "重载*操作符:矩阵乘矩阵**********" << endl;
	matrix9 += 4;
	matrix<int> matrix10(3, 2);
	cin >> matrix10;
	cout << "matrix9 = " << matrix9 << endl;
	cout << "matrix10 = " << matrix10 << endl;
	matrix<int> matrix11 = matrix9*matrix10;
	cout << "matrix11 = matrix9*matrix10:" << matrix11 << endl;
	cout << "重载*操作符:矩阵乘数据**********" << endl;
	matrix<int> matrix12 = matrix11 * 2;
	cout << "matrix12 = matrix11 * 2:" << matrix12 << endl;
	cout << "重载*=操作符:矩阵乘数据*********" << endl;
	matrix12 *= 2;
	cout << "matrix12 *= 2:" << matrix12 << endl;
	cout << "重载/操作符:矩阵除数据**********" << endl;
	matrix<int> matrix13 = matrix12 / 2;
	cout << "matrix13 = matrix12 / 2:" << matrix13 << endl;
	cout << "重载/=操作符:矩阵除数据*********" << endl;
	matrix13 /= 2;
	cout << "matrix13 = " << matrix13 << endl;
	cout << "**********************************matrixTest()函数结束****************************************" << endl;

}

主函数文件:main.cpp

/*
Project name :			allAlgorithmsTest
Last modified Date:		2022年8月13日17点38分
Last Version:			V1.0
Descriptions:			main()函数,控制运行所有的测试函数
*/
#include 
#include "_8matrix.h"

int main()
{	
	matrixTest();	
	return 0;
}

异常类文件:_1myExceptions.h

/*
Project name :			allAlgorithmsTest
Last modified Date:		2022年8月13日17点38分
Last Version:			V1.0
Descriptions:			综合各种异常
*/
#pragma once
#ifndef _MYEXCEPTIONS_H_
#define _MYEXCEPTIONS_H_
#include 
#include

using namespace std;

// illegal parameter value
class illegalParameterValue 
{
   public:
      illegalParameterValue(string theMessage = "Illegal parameter value")
            {message = theMessage;}
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};

// illegal input data
class illegalInputData 
{
   public:
      illegalInputData(string theMessage = "Illegal data input")
            {message = theMessage;}
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};

// illegal index
class illegalIndex 
{
   public:
      illegalIndex(string theMessage = "Illegal index")
            {message = theMessage;}
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};

// matrix index out of bounds
class matrixIndexOutOfBounds 
{
   public:
      matrixIndexOutOfBounds
            (string theMessage = "Matrix index out of bounds")
            {message = theMessage;}
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};

// matrix size mismatch
class matrixSizeMismatch 
{
   public:
      matrixSizeMismatch(string theMessage = 
                   "The size of the two matrics doesn't match")
            {message = theMessage;}
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};

// stack is empty
class stackEmpty
{
   public:
      stackEmpty(string theMessage = 
                   "Invalid operation on empty stack")
            {message = theMessage;}
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};

// queue is empty
class queueEmpty
{
   public:
      queueEmpty(string theMessage = 
                   "Invalid operation on empty queue")
            {message = theMessage;}
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};

// hash table is full
class hashTableFull
{
   public:
      hashTableFull(string theMessage = 
                   "The hash table is full")
            {message = theMessage;}
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};

// edge weight undefined
class undefinedEdgeWeight
{
   public:
      undefinedEdgeWeight(string theMessage = 
                   "No edge weights defined")
            {message = theMessage;}
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};

// method undefined
class undefinedMethod
{
   public:
      undefinedMethod(string theMessage = 
                   "This method is undefined")
            {message = theMessage;}
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};
#endif

你可能感兴趣的:(数据结构,算法与应用,C++语言描述学习笔记,数据结构,算法,c++)