week04测试说明
问题引入:
使用C++编写一个KMatrix容器类,内部可以存储一个二维矩阵数据,并满足以下要求:
1、使用所学的标准容器来组织和存储矩阵数据;2、KMatrix可以存储int/double等常规数值类型,同一个矩阵内部存储的数据类型是一致的;
3、实现KMatrix的初始化函数(KMatrix::init(row_count, col_count))(初始数据为0);
4、实现KMatrix获取行列数的函数(int KMatrix::getRows() const、int
KMatrix::getCols() const);5、实现KMatrix的数据修改与获取函数(KMatrix::setData(row, col, value)、Value
KMatrix::getData(row, col) const);6、实现KMatrix删除行列的函数(KMatrix::erase_row(row)、KMatrix::erase_col(col));
7、实现KMatrix的加(+)、减(-)、叉乘(*) 运算, 使用运算符重载实现;
8、实现KMatrix的转置(KMatrix KMatrix::transpose() const) (交换行列);
9、实现KMatrix的控制台打印输出(KMatrix::print() const) (需要体现矩阵的基本结构);
容器类结构:
template<typename T>
class KMatrix
{
public:
KMatrix() {}
~KMatrix() {}
//进行矩阵的初始化操作
void init(int row, int column) ;
//矩阵行的get操作
int getRows() const;
//矩阵列的get操作
int getCols() const;
//矩阵元素值的set操作
void setData(int row, int col, T value);
//矩阵元素值的get操作
T getData(int row, int col) const;
//删除矩阵特定行的操作
void erase_row(int row);
//删除矩阵特定列的操作
void erase_col(int col);
//"+"运算符重载
friend KMatrix<T> operator+(KMatrix<T>a, KMatrix<T>b);
//"-"运算符重载
friend KMatrix<T> operator-(KMatrix<T>a, KMatrix<T>b);
//"*"运算符重载
friend KMatrix<T> operator*(KMatrix<T>a, KMatrix<T>b);
//"="运算运算符重载
KMatrix<T> operator=(const KMatrix<T>& a);
//矩阵的转置操作
KMatrix<T> transpose() const;
//矩阵的输出
void print();
private:
vector<vector<T>> matrix;
vector<vector<T>>& getMatrix();
};
矩阵类中的方法实现
- 初始化函数:init()
void init(int row, int column) ;
变量:row 行数 column列数
返回值:void类型
具体实现:
void init(int row, int column)
{
matrix.resize(row);
for (int i = 0; i < row; i++)
{
matrix[i].resize(column);
}
}
通过vector容器的resize()方法,对二位数组的行与列进行初始化
- 获取矩阵行数get方法:getRows()
int getRows() const;
具体实现:
int getRows() const
{
return matrix.size();
}
通过vector容器中的size()方法,返回二维vector对象的行数。
- 获取矩阵列数get方法:getCols()
具体实现:
int getCols() const
{
return matrix[0].size();
}
- 获取矩阵某行某列元素值get方法:getData()
具体实现:
T getData(int row, int col) const
{
if (row < matrix.size() && col < matrix[0].size())
{
return matrix[row][col];
}
else
{
cout << "Error! 越界!" << endl;
}
}
- 设置矩阵某行某列元素值set方法:setData()
具体实现:
void setData(int row, int col, T value)
{
if (row < matrix.size() && col < matrix[0].size())
{
matrix[row][col] = value;
}
else
{
cout << "Error! 越界!" << endl;
}
}
- 删除矩阵的顶行的方法:erase_row()
具体实现:
void erase_row(int row)
{
if (row < matrix.size())
{
matrix.erase(matrix.begin() + row);
}
else
{
cout << "Error! 越界!" << endl;
}
}
通过vector容器的erase()方法将目标行删除。
- 删除矩阵特定列的方法:erase_col()
具体实现:
void erase_col(int col)
{
if (col < matrix[0].size())
{
for (int i = 0; i < matrix.size(); i++)
{
matrix[i].erase(matrix[i].begin() + col);
}
}
else
{
cout << "Error! 越界!" << endl;
}
}
同上。
- 矩阵"+"运算符的重载: operator +()
具体实现:
friend KMatrix<T> operator+(KMatrix<T>a, KMatrix<T>b)
{ //能否相加判断
if (a.getRows() != b.getRows() || a.getCols() != b.getCols())
{
cout << "Error!无法相加!" << endl;
}
else
{
KMatrix<T> matrix_add;
matrix_add.init(a.getRows(), a.getCols());
for (int i = 0; i < a.getRows(); i++)
{
for (int j = 0; j < a.getCols(); j++)
{
matrix_add.matrix[i][j] = a.matrix[i][j] + b.matrix[i][j];
}
}
return matrix_add;
}
}
经过边界值判断后通过循环找到目标值,将目标值进行相加赋值给一个局部对象,并将其return出来。
- 矩阵"-"运算符的重载: operator -()
具体实现:
friend KMatrix<T> operator-(KMatrix<T>a, KMatrix<T>b)
{ //能否相减判断
if (a.getRows() != b.getRows() || a.getCols() != b.getCols())
{
cout << "Error!无法相减!" << endl;
}
else
{
KMatrix<T> matrix_reduce;
matrix_reduce.init(a.getRows(), a.getCols());
for (int i = 0; i < a.getRows(); i++)
{
for (int j = 0; j < a.getCols(); j++)
{
matrix_reduce.matrix[i][j] = a.matrix[i][j] - b.matrix[i][j];
}
}
return matrix_reduce;
}
}
跟减法类似。
- 矩阵"*"运算符的重载:operator *()
friend KMatrix<T> operator*(KMatrix<T>a, KMatrix<T>b)
{ //能否相乘判断
if (a.getCols() != b.getRows())
{
cout << "Error!无法相乘!" << endl;
}
else
{
KMatrix<T> matrix_multiply;
matrix_multiply.init(a.getRows(), b.getCols());
for (int i = 0; i < matrix_multiply.getRows(); i++)
{
for (int j = 0; j < matrix_multiply.getCols(); j++)
{
matrix_multiply.matrix[i][j] = 0;
for (int k = 0; k < a.getCols(); k++)
{
matrix_multiply.matrix[i][j] += a.matrix[i][k] * b.matrix[k][j];//乘法计算规则
}
}
}
return matrix_multiply;
}
}
通过三层嵌套循环将满足条件的两个矩阵对应位置的data相乘后累加,放到新矩阵的指定位置。
- 矩阵"="运算都的重载:transpose()
具体实现:
KMatrix<T> operator=(const KMatrix<T>& a)
{
for (int i = 0; i < a.getRows(); i++)
{
for (int j = 0; j < a.getCols(); j++)
{
(*this).matrix[i][j] = a.matrix[i][j];
}
}
return *this;
}
类似于拷贝函数
- 矩阵专职操作函数:transpose() const
具体实现:
KMatrix<T> transpose() const
{
KMatrix<T> temp;
temp.init(this->getCols(), this->getRows());
for (int i = 0; i < this->getRows(); i++)
{
for (int j = 0; j < this->getCols(); j++)
{
temp.matrix[j][i] = this->matrix[i][j];
}
}
return temp;
}
通过循环将 i 行 j 列的元素放到 j 行 i 列。
- 矩阵的打印输出函数:print()
具体实现:
void print()
{
//迭代器定义
vector<vector<int>>::iterator it_one; //内层迭代器
vector<int>::iterator it_two; //外层迭代器
for (it_one = matrix.begin(); it_one != matrix.end(); ++it_one)
{
for (it_two = (*it_one).begin(); it_two != (*it_one).end(); ++it_two)
{
cout << setiosflags(ios::left) << setw(4) << *it_two << ends;
}
cout << endl;
}
}
通过迭代器将二维vector数组内的元素按照矩阵的形式打印出来。
测试样例:
- 测试一:测试矩阵类的初始化函数,以及各种set()与get()方法
- 测试二:测试矩阵的删除行列操作
- 测试三:两个矩阵的相加、相减、相乘、转置操作
- 测试四:内存泄漏测试
主函数
int main()
{
//测试一:测试矩阵类的初始化函数,以及各种set()与get()方法
KMatrix<int> martixOne;
int row_one=0;
int col_one=0;
cout << "------Test One------"<<endl;
cout << "定义矩阵的行数:"; cin >> row_one;
cout << "定义矩阵的列数:"; cin >> col_one;
martixOne.init(row_one, col_one);
for (int i = 0; i < row_one; i++)
{
for (int j = 0; j < col_one; j++)
{
int data;
cout << "请输入 ( " << i << "," << j << " ) 的值:";
cin >> data;
martixOne.setData(i, j, data);
}
}
cout << "矩阵样式为:" << endl;
martixOne.print();
cout << "矩阵行数:" << martixOne.getRows() << endl;
cout << "矩阵列数:" << martixOne.getCols() << endl;
cout << "获取第一行,第二列的值:" << martixOne.getData(0, 1)<<endl;
cout << endl;
//测试二:测试矩阵的删除行列操作
cout << "------Test Two------" << endl;
KMatrix<int> martixTwo;
martixTwo.init(3, 3);//定义矩阵为 3行 3列
/* 1 2 3 矩阵样式
2 4 6
3 6 9 */
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
martixTwo.setData(i, j, (i + 1) * (j + 1));
}
}
cout << "目标矩阵打印" << endl;
martixTwo.print();
//删除第二行,删除第一列
martixTwo.erase_row((2-1));
cout << "删除第二行之后" << endl;
martixTwo.print();
martixTwo.erase_col((1-1));
cout << "删除第一列之后" << endl;
martixTwo.print();
cout << endl;
//测试三:两个矩阵的相加、相减、相乘、转置操作
cout << "------Test Three------" << endl;
KMatrix<int> martixThree; //操作矩阵一 2行 3列
KMatrix<int> martixFour; //操作矩阵二 2行 3列
KMatrix<int> martixFive; //操作矩阵三 3行 2列
/* 1 2 3 操作矩阵一样例
2 4 6 */
martixThree.init(2,3);
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
martixThree.setData(i, j, (i + 1) * (j + 1));
}
}
cout << "操作矩阵一打印样式:" << endl;
martixThree.print();
/* 1 1 1 操作矩阵二样例
1 1 1 */
martixFour.init(2,3);
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
martixFour.setData(i, j, 1);
}
}
cout << "操作矩阵二打印样式:" << endl;
martixFour.print();
/* 2 2 操作矩阵三样例
2 2
2 2 */
martixFive.init(3, 2);
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 2; j++)
{
martixFive.setData(i, j, 2);
}
}
cout << "操作矩阵三打印样式:" << endl;
martixFive.print();
cout << endl;
//矩阵相加测试
cout << "操作矩阵一+操作矩阵二:" << endl;
KMatrix<int> km_add;
km_add.init(2, 3);
km_add = martixThree + martixFour;
cout << "Add_result:" << endl;
km_add.print();
//矩阵相减测试
cout << "操作矩阵一-操作矩阵二:" << endl;
KMatrix<int> km_reduce;
km_reduce.init(2, 3);
km_reduce = martixThree - martixFour;
cout << "reduce_result:" << endl;
km_reduce.print();
//矩阵相乘测试
cout << "操作矩阵一*操作矩阵三:" << endl;
KMatrix<int> km_multiplication;
km_multiplication.init(2, 2);
km_multiplication = martixThree * martixFive;
cout << "multiplication_result:" << endl;
km_multiplication.print();
//矩阵转置测试
cout << "操作矩阵一进行转置:" << endl;
KMatrix<int> km_transpose;
km_transpose.init(3,2);
km_transpose = martixThree.transpose();
cout << "transpose_result:" << endl;
km_transpose.print();
return 0;
}
测试结果
测试四:经过vld内存泄漏测试,未发现程序内存泄漏。