(1)实验目的
通过该实验,让学生理解矩阵压缩存储的概念、方法等相关知识,掌握用三元组表的方式如何进行矩阵的压缩存储,并在此基础上进行转置操作,理解转置和快速转置两种矩阵转置算法的思想。
(2)实验内容
用三元组表压缩存储矩阵,实现创建矩阵、显示以及教材中介绍的两种转置算法。
(3)参考界面
1.创建矩阵
2.销毁矩阵
3.输出矩阵
4.转置矩阵
5.快速转置矩阵
具体要求:请认真查看测试用例
(4)验收/测试用例
- 创建矩阵:
注意:检查非零元素个数是否小于等于行数乘列数;检查是否能拦截元素下标重复输入;检查是否能控制输入的非零元素的下标是递增的(即按照行序输入,先输入小的下标,再输入较大的下标)。
注意:输入的过程中如果有一个输入错了,不要让用户从头再把所有的输入一次,只需把刚才输入错误的,重新输入正确即可。
- 输入:4(行数) 4(列数) 25(非零元个数),会提示:输入错误,非零元素个数要小于等于行数乘列数,请从新输入。
- 输入:4(行数) 4(列数) 5(非零元个数)
- 先输入:(1,1,1) (2,3,2)
- 再输入(2,3,6),会提示:输入错误,输入的下标重复,请重新输入!
- 再输入(1,1,6),会提示:输入错误,输入的下标重复,请重新输入!
- 继续输入(3,1,3) (3,4,5)
- 再输入(3,2,9),会提示:输入错误,下标输入时要递增输入,请重新输入!
- 再输入(2,3,8),会提示:输入错误,下标输入时要递增输入,请重新输入!
- 最后输入(4,2,4)
- 显示
屏幕上输出
1 0 0 0
0 0 2 0
3 0 0 5
0 4 0 0
- 转置
屏幕上输出
1 0 3 0
0 0 0 4
0 2 0 0
0 0 5 0
#include<iostream>
using namespace std;
typedef int ElemType;
#define MAXSIZE 100
typedef struct {
int i;//矩阵的行数
int j;//矩阵的列数
ElemType e;
} Triple;
typedef struct {
Triple data[MAXSIZE + 1];//非零元三元组表,data[0]未使用
int mu, nu, tu;//矩阵的行数,列数和非零元个数
} TSMatrix;
//1.创建矩阵
void CreateSMatrix(TSMatrix& M) {
int mu, nu, tu;
while (1) {//矩阵行数
cout << "请输入行数:" << endl;
cin >> mu;
if (mu <= 0) {
cout << "你输入的行数有误,请重新输入" << endl;
}
else {
M.mu = mu;
cout << "输入行数成功!" << endl;
break;
}
}
while (1) {//矩阵列数
cout << "请输入列数:" << endl;
cin >> nu;
if (nu <= 0 || nu != mu) {//行数必须与列数相同
cout << "你输入的列数有误,请重新输入" << endl;
}
else {
M.nu = nu;
cout << "输入列数成功!" << endl;
break;
}
}
while (1) {//矩阵中非零元素个数
cout << "请输入非零元素个数:" << endl;
cin >> tu;
if (tu<0 || tu>mu * nu) {//非零元个数不能大于元素总个数
cout << "你输入的非零元素个数有误,请重新输入" << endl;
}
else {
M.tu = tu;
cout << "输入非零元素个数成功!" << endl;
break;
}
}
cout << "矩阵的行数为:" << M.mu << endl;
cout << "矩阵的列数为:" << M.nu << endl;
cout<< "矩阵的非零元素个数为:" << M.tu << endl;
int num = 1;
while (num <= M.tu) {//输入从第一行第一列开始对应函数的值
bool flag = true;
int t1, t2, t3;//分别代表用户输入的行,列,非零元的值
cout << "请依次输入行,列,非零元的值" << endl;
cin >> t1;
cin >> t2;
cin >> t3;
for (int temp = 1; temp <= num; temp++) {
if (M.data[temp].i == t1 && M.data[temp].j == t2) {
cout << "输入错误,输入的下标重复,请重新输入!" << endl;
flag = false;
break;
}
else if (t1 <= 0 || t2 <= 0 || t1 > M.mu || t2 > M.nu) {
cout << "输入错误,输入的下标越界,请重新输入!" << endl;
flag = false;
break;
}
else if (t3 == 0) {
cout << "输入错误,应该输入非零元素,请重新输入!" << endl;
flag = false;
break;
}
else if (num > 1 && M.data[num - 1].i > t1) {//num -1 输入位置的前一个数据
cout << "输入错误,下标输入时行要递增输入,请重新输入!" << endl;
flag = false;
break;
}
else if (num > 1 && M.data[num - 1].i == t1 && M.data[num - 1].j > t2) {
cout << "输入错误,下标输入时列要递增输入,请重新输入!" << endl;
flag = false;
break;
}
}
if (flag == true) {
M.data[num].i = t1;
M.data[num].j = t2;
M.data[num].e = t3;
cout << "你已经输入了" << num << "个非零元素" << endl;
num++;
}
}
}
//2.销毁矩阵
void DestorySMatrix(TSMatrix& M) {
for (int i = 1; i <= M.tu; i++) {
M.data[i].e = 0;
}
M.mu = 0;
M.nu = 0;
M.tu = 0;
}
//3.输出矩阵
void PrintSMatrix(TSMatrix M) {
cout << "矩阵为:" << endl;
for (int i = 1; i <= M.mu; i++) {
for (int j = 1; j <= M.nu; j++) {
bool flag = false;
for (int k = 1; k <= M.tu; k++) {
if (i == M.data[k].i && j == M.data[k].j) {
cout << M.data[k].e << " ";
flag = true;
break;
}
}
if (flag == false) {
cout << "0" << " ";
}
}
cout << endl;
}
}
//4.转置矩阵
void TransposeSMatrix(TSMatrix M, TSMatrix& T) {
T.mu = M.mu;
T.nu = M.nu;
T.tu = M.tu;
if (T.tu) {//如果非零元个数不为零则进行转置
int q = 1;
for (int col = 1; col <= M.nu; ++col) {
for (int p = 1; p <= M.tu; ++p) {
if (M.data[p].j == col) {
T.data[q].i = M.data[p].j;
T.data[q].j = M.data[p].i;
T.data[q].e = M.data[p].e;
++q;
}
}
}
}
}
//5.快速转置矩
void FastTransposeSMatrix(TSMatrix M, TSMatrix& T) {
int num[MAXSIZE] = {}, cpot[MAXSIZE] = {};
T.mu = M.nu;
T.nu = M.mu;
T.tu = M.tu;
if (T.tu) {
for (int col = 1; col <= M.nu; ++col) {
num[col] = 0;
}
for (int t = 1; t <= M.tu; ++t) {
++num[M.data[t].j];
}
cpot[1] = 1;
for (int col = 2; col <= M.nu; ++col) {
cpot[col] = cpot[col - 1] + num[col - 1];
}
for (int p = 1; p <= M.tu; ++p) {
int col = M.data[p].j;
int q = cpot[col];
T.data[q].i = M.data[p].j;
T.data[q].j = M.data[p].i;
T.data[q].e = M.data[p].e;
++cpot[col];
}
}
}
int main() {
TSMatrix M;
int temp = false;
int n = 1;//退出菜单的标记
cout << "1----创建矩阵" << endl;
cout << "2----销毁矩阵" << endl;
cout << "3----输出矩阵" << endl;
cout << "4----矩阵转置" << endl;
cout << "5----快速矩阵转置" << endl;
cout << "输入一个负数退出!" << endl;
while (n) {//当n的值不为0时,通过while实现循环
cout << "~~~~~~~~~~~~~~~~~~~~~" << endl;
cout << "请输入你的选择:";
int option;
cin >> option;//选择操作号
switch (option) {
case 1:
CreateSMatrix(M);
cout << "初始化成功" << endl;
temp = true;
break;
case 2:
if (temp == false) {
cout << "请先初始化矩阵" << endl;
}
else {
DestorySMatrix(M);
cout << "摧毁矩阵成功" << endl;
temp = false;
}
break;
case 3:
if (temp == false) {
cout << "请先初始化矩阵" << endl;
}
else {
PrintSMatrix(M);
}
break;
case 4:
if (temp == false) {
cout << "请先初始化矩阵" << endl;
}
else {
TSMatrix T;
TransposeSMatrix(M, T);
PrintSMatrix(T);
}
break;
case 5:
if (temp == false) {
cout << "请先初始化矩阵" << endl;
}
else {
TSMatrix T;
FastTransposeSMatrix(M, T);
PrintSMatrix(T);
}
break;
default:
if (option < 0) {
n = 0;
cout << "程序退出成功,欢迎下次使用" << endl;
break;
}
else
cout << "您输入的指令有误,请重新输入" << endl;
}
}
}