文章目录
一、目的
1.了解稀疏矩阵相乘运算特点
2.知道稀疏矩阵存储,创建,显示,转置方法
二、设计要求
1.问题描述
利用稀疏的特点进行存储和计算可大大节省存储空间,并实现稀疏矩阵相乘运算
2.需求分析
(1)用三元组顺序表表示稀疏矩阵,用来实现两个矩阵相乘运算
(2)使用三元组表示稀疏矩阵的输入形式,以阵列形式列出运算结果
(3)先让用户输入矩阵的列数和行数,给出的两个矩阵行,列数是否和所要求的相对应
(4)列出菜单项,用户根据菜单进行所有操作
三、概要设计
1.主界面设计
(1)创建矩阵,输入非零元的行数列数,以及非零元个数
(2)按照行的顺序,写出两个矩阵所在非零元的数值
(3)根据菜单,再次输入
2.存储结构设计
稀疏矩阵存储结构用三元组顺序表示
//三元组的定义:
typedef struct
{
int row; //行下标
int col; //列下标
int e; //元素值
}Triple;
//矩阵的定义;
typedef struct
{
Triple data[MAXSIZE]; //三元组表
int m ,n ,len; //行,列,非零元个数
}TSMatrix;
3.系统功能设计
此系统通过菜单让用户输入数据后创建两个矩阵,接着对两个矩阵相乘运算,并输出结果,以此
实现以下功能
(1)首先创建两个矩阵,用户输入的行和列数,非0元个数,以及所有非零元的行列值
(2)其次两个矩阵相乘,由mult函数实现,输出矩阵A,B及(A*B)的阵列形式
四、模块设计
1.模块设计
此程序包含两个模块,主程序模块,矩阵运算模块
其调用关系是:主程序模块→矩阵运算模块
2.系统子程序及功能设计
此系统一共有7个子程序,子程序的功能和函数名如下:
(1)矩阵初始化
void initMatrix(TSMatrix *A)
(2)创建矩阵,调用(1)
void createTSMatrix(TSMatrix *A)
(3)找到m行n列元素在矩阵A的三元组表中的位置
int search(TSMatrix *A,int m, int n)
(4)两个矩阵相乘,调用(3)
void mult(TSMatrix *A,TSMatrix *B,TSMatrix *C)
(5)输出的矩阵
void print(TSMatrix *A)
(6)显示程序主函数,工作区函数
void showtip()
(7)主函数
void main()
3.函数主要调用关系
主函数7调用函数2,4,5,6
函数2在调用函数1,函数4再调用函数3
五、详细设计
1.数据类型定义
采用矩阵的三元组顺序表存储结构
//三元组的定义:
typedef struct
{
int row; //行下标
int col; //列下标
int e; //元素值
}Triple;
//矩阵的定义;
typedef struct
{
Triple data[MAXSIZE]; //三元组表
int m ,n ,len; //行,列,非零元个数
}TSMatrix;
2.主要子程序详细设计
(1)主函数模块设计
int main()
{
TSMatrix A,B,C;
createTSMatrix(&A);
createTSMatrix(&B);
MulTSMatrix(&A,&B,&C);
printMatrix(&C);
return 0;
}
(2)创建矩阵
void createTSMatrix(TSMatrix *A)//创建矩阵
{ int i=0; //data未用
scanf("%d?%d",&A->m,&A->n);
int flag = 1;
int a,b,c;
char c1,c2,c3;
while(flag)
{
scanf("%d?%d?%d",&a,&b,&c);
if(a==0&&b==0&&c==0)
break;
i++;
A->data[i].row=a;
A->data[i].col=b;
A->data[i].e=c;
}
A->len=i;
}
(3)输出矩阵
void print(TSMatrix *B)//输出矩阵
{
for(int i=1;i<=B->len;i++)
{
printf("%d?%d?%d\n",B->data[i].row,B->data[i].col,B->data[i].e);
}
}
(4)矩阵相乘
void mult(TSMatrix *A,TSMatrix *B,TSMatrix *C)//矩阵相乘
{
C->len=0;
int p,q,x,cnt;
int i1,j1;
int sum;
cnt=1;
for(int i=1;i<=A->m;i++)
{
for(int j=1;j<=B->n;j++)//遍历每行每列
{
sum=0;
for(int k=1;k<=A->n;k++)//每个行与每个列单个数的遍历
{ p=0;q=0;
for(i1=1;i1<=A->len;i1++){ //遍历A找符合i行k列的数
if(A->data[i1].row==i&&A->data[i1].col==k) p=A->data[i1].e;
}
for(j1=1;j1<=B->len;j1++){//遍历B找符合k行j列的数
if(B->data[j1].row==k&&B->data[j1].col==j) q=B->data[j1].e;
}
sum=sum+(p*q);
}
if(sum!=0) {cnt++;
C->data[cnt].e=sum;
C->data[cnt].row=i;
C->data[cnt].col=j;
}
}
C->len=cnt;
}