《数据结构、算法与应用C++语言描述》使用C++语言实现二维数组矩阵
行主映射与列主映射
如图7-2所示。
行主映射:从第一行开始,依次对每一行的索引从左至右连续编号。
列主映射:对索引的编号从最左列开始,依次对每一列的索引从上到下连续编号。
行主映射的映射函数:
列主映射的映射函数:
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)。
矩阵运算
矩阵转置:一个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
cpp
/*
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<iostream>
#include <algorithm>
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();
//<<和>>没有加<T>之前一直报错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
cpp
/*
Project name : allAlgorithmsTest
Last modified Date: 2022年8月13日17点38分
Last Version: V1.0
Descriptions: 测试_8matrix.h头文件中的所有函数
*/
#include"_8matrix.h"
#include<iostream>
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
cpp
/*
Project name : allAlgorithmsTest
Last modified Date: 2022年8月13日17点38分
Last Version: V1.0
Descriptions: main()函数,控制运行所有的测试函数
*/
#include <iostream>
#include "_8matrix.h"
int main()
{
matrixTest();
return 0;
}
异常类文件:_1myExceptions.h
cpp
/*
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 <string>
#include<iostream>
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