# 数据结构课程设计大曝光(3) **注:转发请注明出处,以免老师误以为本人抄袭……** [TOC] # 课程设计三 稀疏矩阵的转置、加法和乘法的实现 ## 一、实习目的和任务: ### 【问题描述】 设计一个程序,演示用三元组和十字链表表示的稀疏矩阵的转置、加法和乘法的实现。 ### 【基本要求】 - (1)演示稀疏矩阵A的三元组和十字链表的建立过程。 - (2)演示稀疏矩阵A的转置过程。 - (3)演示稀疏矩阵A和B 的相加过程。 - (4)演示稀疏矩阵A和B 的相乘过程。 ## 二、概要设计: **设计思路:演示三元组矩阵的的创建转置和十字链表的转置、加法和乘法** ### 1.三元组的顺序结构实现: #### ADT TSMatrix;{ 数据对象:D={aij|i=1,2,……,m;j=1,2,……n,ai,j∈ElemSet,m,n分别成为矩阵的行数和列数} 数据关系:R={Row,Col} Row={<ai,j,ai,j+1>|1≤i≤m,1≤j≤n-1} Col={<ai,j,ai+1,j>|1≤i≤m-1,1≤j≤n} 基本操作: #### void initTS(TSMatrix &T) 操作结果:初始化三元组顺序表 #### Status CreateTS(TSMatrix &T) 初始条件:三元组顺序表T已存在 操作结果:由键盘输入创建三元组稀疏矩阵 #### void printTS(TSMatrix &t) 初始条件:三元组顺序表T已存在 操作结果:输出三元组数据 #### void printTM(TSMatrix &t) 初始条件:三元组顺序表T已存在 操作结果:输出三元组矩阵 #### Status TransposeSMatrix(TSMatrix &M,TSMatrix &T) 初始条件:三元组顺序表M,T已存在 操作结果:采用三元组表存储表示,求稀疏矩阵M的转置矩阵T #### Status TransposeSMSelf(TSMatrix &M) 初始条件:三元组顺序表T已存在 操作结果:采用三元组表存储表示,将稀疏矩阵M自身转置 #### }ADT TSMatrix; ### 2、十字链表结构的实现: #### ADT CrossList;{ 数据对象:D={aij|i=1,2,……,m;j=1,2,……n,ai,j∈ElemSet,m,n分别成为矩阵的行数和列数} 数据关系:R={Row,Col} Row={<ai,j,ai,j+1>|1≤i≤m,1≤j≤n-1} Col={<ai,j,ai+1,j>|1≤i≤m-1,1≤j≤n} 基本操作: #### void InitCrossList(CrossList &M) 操作结果:初始化十字链表M #### void destroyOLNode(OLink o) 初始条件:十字链表行指针o指向的行存在 操作结果:利用递归销毁一行的节点 #### void destroyMatrix_OL(CrossList &c) 初始条件:十字链表c已存在 操作结果:销毁十字链表 #### Status initMatrixSize(CrossList &c,int mu,int nu) 初始条件:十字链表c已存在 操作结果:根据行数,列数初始化链表结构 #### Status InsertNode(CrossList &M,int i,int j,int e) 初始条件:十字链表M已存在 操作结果:在十字链表M中插入节点(任意位置) #### Status CreateSMatrx_OL(CrossList &M) 初始条件:十字链表M已存在 操作结果:创建稀疏矩阵M,采用十字链表存储表示 #### Status insertLastNode(CrossList &c,int i,int j,int e) 初始条件:十字链表c已存在 操作结果:往行尾及列尾端插入节点(只有在确定插入节点在末尾才能用,为矩阵的转置,加法,乘法定制的函数) #### Status TransposeMatrix(CrossList &m,CrossList &l) 初始条件:十字链表m,l已存在 操作结果:将矩阵m转置赋值给l #### Status PlusMatrix(CrossList &a,CrossList &b,CrossList &c) 初始条件:十字链表a,b,c已存在 操作结果:将矩阵a与b的和赋值给c #### Status MultMatrix(CrossList &a,CrossList &b,CrossList &c) 初始条件:十字链表a,b,c已存在 操作结果:将矩阵a与b的积赋值给c #### Status printOLNOde(OLink p) 操作结果:输出十字链表节点,用作遍历函数 #### Status TraverseCL(CrossList &c,Status (* visit)(OLink p)) 初始条件:十字链表c已存在 操作结果:十字链表的逐行遍历 #### Status printCL(CrossList &c) 初始条件:十字链表c已存在 操作结果:输出十字链表矩阵的三元组表示 #### Status TransNode(OLink p) 初始条件:十字链表节点p已存在 操作结果:将节点中的行列及指针进行交换 #### Status TransposeSelf(CrossList &m) 初始条件:十字链表m已存在 操作结果:将矩阵m自身转置 #### void printCLMatrix(CrossList &c) 初始条件:十字链表c已存在 操作结果:输出十字链表矩阵的矩阵表示 #### }ADT CrossList; ### 3、用户交互的实现: - char *oprcmd="CcMmTtSs'";-------------------------定义用户可以使用的操作 - char *opecmd="LlMmTtNnUu"----------------------定义用户可以使用的操作数 - char *spccmd="+*HhEeXx\033"----------------------定义用户可以使用的命令 - instr(char cmd,char *precmd)---------------判断c是否在str中,用于命令判断 - int isCmd(char *cmd) -----------------------判断是否为可识别的命令 - void Pause() -----------------------------------暂停并按任意键继续 - void Help() ------------------------------------输出命令帮助 - void openScreen()-----------------------------输出开始界面 - void inCMD(char *cmd)---------------------命令输入 - void Goodbye(CrossList &l,CrossList &m,CrossList &n)----------------退出界面并完成销毁工作 - void CMDtran(char* c,CrossList &l,CrossList &m,CrossList &n,TSMatrix &t,TSMatrix &u)------------解释命令并执行 - void CMDTrans(int &step,int &n,char *s,SqStack &a,SqStack &b,SqStack &c)----------------------------将字符串命令解释执行并输出执行后的汉诺塔状态 ### 4、其他 - void swap(int &a,int &b)---------------交换a,b两元素的值 - int getint(int &n)-------------------------从键盘得到一个整数值 ## 三、程序代码: ```C /*------------------------------------------------- 三元组表示的稀疏矩阵的转置、加法和乘法的实现。 【问题描述】 设计一个程序,演示用三元组和十字链表表示的稀疏矩阵的转置、加法和乘法的实现。 【基本要求】 (1)演示稀疏矩阵A的三元组和十字链表的建立过程。 (2)演示稀疏矩阵A的转置过程。 (3)演示稀疏矩阵A和B 的相加过程。 (4)演示稀疏矩阵A和B 的相乘过程。 -----------------------------------------------*/ #include "stdio.h" #include "stdlib.h" #include "conio.h" #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2 //Status 是函数的类型,其值是函数结果状态代码 typedef int Status; typedef int ElemType;//元素类型 void swap(int &a,int &b) {//交换a,b两元素的值 int temp; temp=a; a=b; b=temp; }//swap int getint(int &n) {//输入整数值 n=0; char c; do{ do{ c=getch(); }while((c>'9'||c<'0')&&c!='\015'&&c!='\b'&&c!=' '||(c=='\015'&&n==0)||(c==' '&&n==0)); if(c>='0'&&c<='9'){ n=n*10+(c-'0'); if(!(n==0&&c=='0'))putch(c); }else if(c=='\b'&&n!=0){ printf("\b \b"); n=n/10; }else if(c=='\015'||c==' ') putch('\012'); }while(c!='\015'&&c!=' '); return n; }//getint //--------------------------稀疏矩阵的三元组顺序表存储表示---------------------- #define MAXSIZE 500 //假设矩阵非零元个数的最大值为500 #define MAXRC 1000//假设矩阵最多为1000行 typedef struct { int i,j;//该非零元的行下标和列下标 ElemType e; }Triple; typedef struct{ Triple data[MAXSIZE+1];//非零元三元组表,data[0]未用 int mu,nu,tu;//矩阵的行数、列数和非零元个数 }TSMatrix; Status CreateTS(TSMatrix &T){//创建三元组稀疏矩阵 int k,mu,nu,tu; printf("输入行数,列数和非零元个数\n"); // scanf("%d%d%d",&mu,&nu,&tu); do{ printf("请输入行数:");getint(mu); printf("请输入列数:");getint(nu); printf("请输入非零元个数:");getint(tu); }while(mu*nu<tu); if(tu>MAXSIZE)return OVERFLOW; T.tu=tu;T.mu=mu;T.nu=nu; printf("请按照顺序输入其行号、列号及非零元(不按顺序或输入重复元素会出现意想不到的错误)\n"); for(k=1;k<=tu;k++){ // scanf("%d%d%d",&i,&j,&e); printf("---------第%d个非零元---------\n",k); do{printf("请输入行号:");getint(T.data[k].i);}while(T.data[k].i>mu); do{printf("请输入列号:");getint(T.data[k].j);}while(T.data[k].j>nu); printf("请输入非零元数据:");getint(T.data[k].e); }//for return OK; }//CreateTS void initTS(TSMatrix &T) {//初始化三元组链表 T.mu=0;T.nu=0;T.tu=0; }//initTS void printTS(TSMatrix &t){//输出三元组数据 int i; printf("三元组矩阵有%d行%d列%d个非零元\n",t.mu,t.nu,t.tu); printf("以下为其数据元素:\n"); for(i=1;i<=t.tu;i++) printf("\t%d\t%d\t%d\t\n",t.data[i].i,t.data[i].j,t.data[i].e); }//printTS void printTM(TSMatrix &t){//输出三元组矩阵 int x,y,z=1; for(x=1;x<=t.mu;x++){//行循环 for(y=1;y<=t.nu;y++){//列循环 if(t.data[z].i==x&&t.data[z].j==y){//当前元素为非零元 printf("\t%d",t.data[z].e);z++; }//if else//当前元素为零元 printf("\t0"); }//for printf("\n");//换行,准备输出下一行 }//for }//printTM Status TransposeSMatrix(TSMatrix &M,TSMatrix &T){ //采用三元组表存储表示,求稀疏矩阵M的转置矩阵T int q,col,p;//非零元,行,列 循环变量 T.mu=M.mu;T.nu=M.mu;T.tu=M.tu; if(T.tu){ q=1; for(col=1;col<=M.nu;++col) for(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; }//if }//if return OK; }//TransposeSMatrix Status TransposeSMSelf(TSMatrix &M){ //采用三元组表存储表示,将稀疏矩阵M自身转置 int q=1,md,p; if(M.tu){//交换行列号 for(p=1;p<=M.tu;++p) swap(M.data[p].i,M.data[p].j); for(p=1;p<M.tu;++p){//进行排序 md=p; for(q=p;q<=M.tu;++q){//选择排序,比较过程 if(M.data[md].i>M.data[q].i||(M.data[md].i==M.data[q].i&&M.data[md].j>M.data[q].j)) md=q; } if(md!=p){//选择排序,交换过程 swap(M.data[p].i,M.data[md].i); swap(M.data[p].j,M.data[md].j); swap(M.data[p].e,M.data[md].e); }//if } }//if return OK; }//TransposeSMatrix //----------------稀疏矩阵的十字链表 存储结构 定义-------------------------- typedef struct OLNode{//十字链表的三元组结构体 int i,j;//该非零元的行和列下标 ElemType e;//数据元素 struct OLNode *right,*down;//该非零元所在行表和列表的后继链域 }OLNode,* OLink; typedef struct { OLink *rhead,*chead;//行和列链表头指针向量基址由CreateSMatrix分配 int mu,nu,tu;//系数矩阵的行数列数和非零元个数 }CrossList; //----------------稀疏矩阵的十字链表 函数实现-------------------------- void InitCrossList(CrossList &M) {//初始化十字链表 M.mu=0;M.nu=0;M.tu=0; M.chead=NULL;M.rhead=NULL; }//InitCrossList void destroyOLNode(OLink o) {//利用递归销毁一行的节点 if(o->right)destroyOLNode(o->right); free(o); }//destroyOLNode void destroyMatrix_OL(CrossList &c) {//销毁十字链表 int i; for(i=1;i<=c.nu;i++) { if(c.rhead[i]) destroyOLNode(c.rhead[i]); }//for free(c.chead); free(c.rhead); c.mu=0;c.nu=0;c.tu=0; }//destroyMatrix_OL Status initMatrixSize(CrossList &c,int mu,int nu) {//根据行数,列数初始化链表结构 int i; if(c.tu||c.nu)destroyMatrix_OL(c); c.mu=mu;c.nu=nu; //给行列头指针分配空间 if(!(c.rhead=(OLink *)malloc((mu+1)*sizeof(OLink))))exit(OVERFLOW); if(!(c.chead=(OLink *)malloc((nu+1)*sizeof(OLink))))exit(OVERFLOW); //初始化行列头指针向量,各行列链表为空链表 for(i=0;i<=mu;i++) c.rhead[i]=NULL; for(i=0;i<=nu;i++) c.chead[i]=NULL; return OK; } Status InsertNode(CrossList &M,int i,int j,int e) {//插入节点(任意位置) OLink p,q; if(!(p=(OLNode *)malloc(sizeof(OLNode))))exit(OVERFLOW); p->i=i;p->j=j;p->e=e;p->down=NULL;p->right=NULL;//生成节点 if(M.rhead[i]==NULL||M.rhead[i]->j>j){ p->right=M.rhead[i];M.rhead[i]=p; }//if else if(M.rhead[i]==NULL||M.rhead[i]->j==j){ free(p);return ERROR; }//else if else {//巡查在行表中的插入位置 for(q=M.rhead[i];(q->right)&&q->right->j<j;q=q->right); if(q->right!=NULL&&q->right->j==j){ free(p);return ERROR; }//if p->right=q->right;q->right=p; }//else if //完成行插入 if(M.chead[j]==NULL||M.chead[j]->i>i){p->down=M.chead[j];M.chead[j]=p;}//if else{//巡查在列表中的插入位置 for(q=M.chead[j];(q->down)&&q->down->i<i;q=q->down); p->down=q->down;q->down=p; }//else if //完成列插入 return OK; }//InsertNOde Status CreateSMatrx_OL(CrossList &M){ //创建稀疏矩阵M,采用十字链表存储表示 int m,n,t,i,j,k; ElemType e; printf("输入行数,列数和非零元个数\n"); // scanf("%d%d%d",&m,&n,&t); //输入M的行数,列数和非零元个数 do{ printf("请输入行数:");getint(m); printf("请输入列数:");getint(n); printf("请输入非零元个数:");getint(t); }while(m*n<t); // if(m*n<t)return ERROR;//行列乘积不能大于非零元个数 initMatrixSize(M,m,n);//根据行数,列数初始化链表结构 M.tu=t; //初始化非零元个数 printf("输入其行号、列号及非零元(可以不按顺序)\n"); for(k=1;k<=M.tu;k++){//按任意顺序输入非零元 // scanf("%d%d%d",&i,&j,&e); printf("----------第%d个非零元----------\n",k); do{printf("请输入行号:");getint(i);}while(i>m); do{printf("请输入列号:");getint(j);}while(j>n); printf("请输入非零元数据:");getint(e); if(!InsertNode(M,i,j,e)){k--;}; }//for return OK; }//CreateSMatrx_OL Status insertLastNode(CrossList &c,int i,int j,int e) {//往行尾及列尾端插入节点(只有在确定插入节点在末尾才能用,为矩阵的转置,加法,乘法定制的函数) OLink r,*s; if(!(r=(OLNode *)malloc(sizeof(OLNode))))exit(OVERFLOW); r->i=i;r->j=j;r->e=e;r->right=NULL;r->down=NULL;//给节点赋值 for(s=&(c.rhead[i]);(*s);s=&((*s)->right));(*s)=r;//巡查在行表中的插入位置并插入 for(s=&(c.chead[j]);(*s);s=&((*s)->down));(*s)=r;////巡查在列表中的插入位置并插入 return OK; } Status TransposeMatrix(CrossList &m,CrossList &l) {//将矩阵m转置赋值给l OLink p;//循环,临时指针 int i;//循环变量 initMatrixSize(l,m.nu,m.mu);//根据行数,列数初始化链表结构 l.tu=m.tu;//初始化非零元个数 for(i=1;i<=m.nu;i++) {//逐行计算 for(p=m.rhead[i];p;p=p->right){ insertLastNode(l,p->j,p->i,p->e);//往行尾及列尾端插入节点 }//for }//for return OK; }//TransposeMatrix Status PlusMatrix(CrossList &a,CrossList &b,CrossList &c) {//将矩阵a与b的和赋值给c OLink p,q;//循环,临时指针 int i,j,e,k=0;//循环变量 ,临时数据 ,累计非零元个数 if(a.mu!=b.mu||a.nu!=b.nu)return ERROR; initMatrixSize(c,a.mu,a.nu);//根据行数,列数初始化链表结构 for(i=1;i<=a.mu;i++){//逐行计算 p=a.rhead[i];q=b.rhead[i]; while(p||q) {//对此行中每个非零元遍历 if((p&&q)&&(p->j==q->j&&p->e+q->e==0)) {//不需要插入节点时的情况 p=p->right;q=q->right; }//if else{//需要插入节点时的情况 if(q==NULL){//b中此行已无非零元 j=p->j; e=p->e; p=p->right; }//else if else if(p==NULL){//a中此行已无非零元 j=q->j;e=q->e;q=q->right; }//else if else if(p->j<q->j){ j=p->j;e=p->e;p=p->right; }//else if else if(p->j>q->j){ j=q->j;e=q->e;q=q->right; }//else if else if(p->j==q->j){ j=q->j;e=p->e+q->e;p=p->right;q=q->right; }//else if k++; insertLastNode(c,i,j,e);//往行尾及列尾端插入节点 }//else }//while }//for c.tu=k; return OK; }//PlusMatrix Status MultMatrix(CrossList &a,CrossList &b,CrossList &c) {//将矩阵a与b的积赋值给c OLink p,q;//循环,临时指针 int i,j,e,k;//循环变量 ,临时数据,非零元个数累加器 if(a.mu!=b.nu||a.nu!=b.mu)return ERROR; initMatrixSize(c,a.mu,b.nu);//根据行数,列数初始化链表结构 for(i=1;i<=a.mu;i++){//a的行 for(j=1;j<=b.nu;j++){//b的列 p=a.rhead[i];q=b.chead[j];e=0;//循环初值 while(p&&q) { if(p->j<q->i)p=p->right; else if(p->j>q->i)q=q->down; else if(p->j==q->i){//对应元素 e+=(p->e)*(q->e);//相乘并累加 p=p->right;q=q->down; }//else if }//while if(e!=0){//当元素不为0时插入节点 k++; insertLastNode(c,i,j,e);//往行尾及列尾端插入节点 }//if }//for }//for c.tu=k; return OK; }//MultMatrix Status printOLNOde(OLink p) {//输出十字链表节点,用作遍历函数 printf("\t%d\t%d\t%d\t\n",p->i,p->j,p->e); return OK; }//printOLNOde Status TraverseCL(CrossList &c,Status (* visit)(OLink p)) {//十字链表的逐行遍历 int i; OLink p; for(i=1;i<=c.mu;i++) {//逐行计算 for(p=c.rhead[i];p;p=p->right)//对此行中每个非零元遍历 if(!visit(p))return ERROR; }//for return OK; }//TraverseCL Status printCL(CrossList &c) {//输出十字链表矩阵的三元组表示 printf("十字链表矩阵有%d行%d列%d个非零元\n",c.mu,c.nu,c.tu); printf("以下为其数据元素:\n"); printf("\t\t\t\t\n"); TraverseCL(c,printOLNOde); return OK; }//printCL Status TransNode(OLink p) {//将节点中的行列及指针进行交换 swap(p->i,p->j); swap((int &)p->right,(int &)p->down); return OK; }//TransNode Status TransposeSelf(CrossList &m) {//将矩阵m自身转置 swap((int &)m.chead,(int &)m.rhead);//先交换行列表头 TraverseCL(m,TransNode);//然后用交换节点行列及指针的函数遍历十字链表 return OK; }//TransposeMatrix void printCLMatrix(CrossList &c) {//输出十字链表矩阵的矩阵表示 int i,j; OLink p; for(i=1;i<=c.nu;i++) {//行 p=c.rhead[i]; for(j=1;j<=c.mu;j++) {//列 if(p&&j==p->j) {//此元素为非零元 printf("\t%d",p->e); p=p->right; }//if else {//此元素为零元 printf("\t0"); }//else }//for(j) printf("\n"); }//for(i) }//printCLMatrix //------------------------------命令及界面 函数 定义 开始----------------------- void Pause() {//按任意键继续 printf("\n按任意键继续……\n"); getch(); }//Pause void Goodbye(CrossList &l,CrossList &m,CrossList &n) {//显示结束画面,并结束程序 //用完销毁 destroyMatrix_OL(l);destroyMatrix_OL(m);destroyMatrix_OL(n); system("cls");//清屏 printf("\n\n\n\n\t\t\tGoodbye\n\n"); printf("\t\t\t\t******CopyLeft#WrittenByhuaying1988.com******\n\n"); Pause();//按任意键继续 exit(0); }//Goodbye void Help() {//命令帮助 printf("命令说明:\n\ cx------------------建立/重建矩阵x并输出\n\ mx------------------以矩阵形式输出矩阵x\n\ tx------------------以三元组形式输出矩阵x\n\ sx------------------将x自身转置并输出x\n\ 'x------------------计算并输出x的转置(三元组存入u中,十字链表存入n中)\n\ + ------------------计算n=l+m并输出\n\ * ------------------计算n=l*m并输出\n\ H-------------------(help)命令帮助\n\ E/X-----------------(exit)退出\n\ 不区分大小写,不允许有多余字符,其中的'x'处只可以是t,m,l,n,u\n\ 其中t为三元组表示的稀疏矩阵,m,l为十字链表表示的稀疏矩阵\n"); }//Help void OpenScreen() {//开始画面 system("color f0"); system("title 十字链表矩阵运算演示程序 WrittenBy huaying1988.com"); printf("\n\n\n\t\t\t十字链表矩阵运算演示程序\n"); printf("\t\t\t**学院 **07-*\n"); printf("\t\t\thuaying1988.com 学号:***********\n"); printf("\n\t说明:\n\ 演示用三元组和十字链表表示的稀疏矩阵的转置、加法和乘法的实现\n\n"); printf("\t\t\t\t******CopyLeft#WrittenByhuaying1988.com******\n\n"); Pause(); system("cls"); Help(); }//OpenScreen void CMDtran(char* c,CrossList &l,CrossList &m,CrossList &n,TSMatrix &t,TSMatrix &u) {//解释命令并执行 void *ope=NULL,*fun=NULL; int flag=0;//标志操作三元组(1)或十字链表(2) switch(c[1]) {//操作数 case 't': case 'T': ope=(void *)&t; flag=1; break; case 'l': case 'L': ope=(void *)&l; flag=2; break; case 'm': case 'M': ope=(void *)&m; flag=2; break; case 'N': case 'n': ope=(void *)&n; flag=2; break; case 'U': case 'u': ope=(void *)&u; flag=1; break; default:flag=0; }//switch c[1] switch(c[0]) {//操作符 case 'H'://pass through case 'h'://命令帮助 Help(); return; case 27://pass through case 'x': case 'X': case 'e'://pass through case 'E'://退出 Goodbye(l,m,n);//三元组不用销毁 //exit(0); break; case '+': PlusMatrix(l,m,n); printf("m与l的和:\n"); printCLMatrix(n); break; case '*': MultMatrix(l,m,n); printf("m与l的积:\n"); printCLMatrix(n); break; case 'c': case 'C': if(flag==2){ if((*(CrossList *)ope).tu>0){ printf("矩阵%c已存在,是否重建?(y/*)\n",c[1]); if(getch()=='y'){ printf("建立十字链表矩阵%c:\n",c[1]); CreateSMatrx_OL(*(CrossList *)ope); printf("矩阵%c已建立:\n",c[1]); printCLMatrix(*(CrossList *)ope); }else printf("用户撤销重建……\n"); }//if else{ printf("建立十字链表矩阵%c:\n",c[1]); CreateSMatrx_OL(*(CrossList *)ope); printf("矩阵%c已建立:\n",c[1]); printCLMatrix(*(CrossList *)ope); }//else }//if else if(flag==1){ if((*(CrossList *)ope).tu>0){ printf("矩阵%c已存在,是否重建?(y/*)\n",c[1]); if(getch()=='y'){ printf("建立三元组矩阵t:\n"); CreateTS(*(TSMatrix *)ope); printf("矩阵t已建立:\n"); printTM(*(TSMatrix *)ope); }else printf("用户撤销重建……\n"); }//if else{ printf("建立三元组矩阵t:\n"); CreateTS(*(TSMatrix *)ope); printf("矩阵t已建立:\n"); printTM(*(TSMatrix *)ope); }//else }//else if break; case 'm': case 'M': if(flag)printf("矩阵%c:\n",c[1]); if(flag==2)printCLMatrix(*(CrossList *)ope); else if(flag==1)printTM(*(TSMatrix *)ope); break; case 't': case 'T': if(flag)printf("矩阵%c:\n",c[1]); if(flag==2)printCL(*(CrossList *)ope); else if(flag==1)printTS(*(TSMatrix *)ope); break; case 's': case 'S': if(flag)printf("转置后矩阵%c变为:\n",c[1]); if(flag==2){ TransposeSelf(*(CrossList *)ope); printCLMatrix(*(CrossList *)ope); }//if else if(flag==1){ TransposeSMSelf(*(TSMatrix *)ope); printTM(*(TSMatrix *)ope); }//else if break; case '\047'://' if(flag)printf("矩阵%c的转置为:\n",c[1]); if(flag==2){ TransposeMatrix(*(CrossList *)ope,n); printCLMatrix(n); }//if else if(flag==1){ TransposeSMatrix(*(TSMatrix *)ope,u); printTM(u); }//else if break; default://其他输入 printf("不能识别的命令\n"); }//switch c[0]; }//CMDtran void inCMD(char *cmd) {//命令输入函数 printf("\nh-help,e-exit|请输入命令:\n"); scanf("%s",cmd); putch('\n'); }//inCMD int instr(char cmd,char *precmd) {//判断是否为命令 int i; for(i=0;precmd[i]!='\0';i++) { if(precmd[i]==cmd)return 1; }//for return 0; }//instr char *oprcmd="CcMmTtSs'";//操作 char *opecmd="LlMmTtNnUu";//操作数 char *spccmd="+*HhEeXx\033";//命令 int isCmd(char * cmd) {//判断是否为命令 if((instr(cmd[0],spccmd)&&cmd[1]==0)||(instr(cmd[0],oprcmd)&&instr(cmd[1],opecmd)&&cmd[2]==0)) return 1; printf("无法识别的命令\n"); return 0; }//isCmd //-----------------------------命令及界面 函数 定义 结束----------------------- int main() { CrossList l,m,n;TSMatrix t,u;//声明 char cmd[100]={0};//用来存储命令 InitCrossList(l);InitCrossList(m);//初始化 InitCrossList(n);initTS(t);initTS(u); OpenScreen();//开始画面 while(1){ do{//如果输入不是命令则重复输入 inCMD(cmd); }while(!isCmd(cmd)); CMDtran(cmd,l,m,n,t,u); } return 0; } ``` ## 四、测试数据及结果分析: **运行界面:** ![运行界面](matrix.jpg "运行界面") 开始画面以后,显示命令说明和命令提示符,输入“ct”,回车,按提示依次输入: ``` 建立三元组矩阵t: 请输入行数,列数和非零元个数 请输入行数:4 请输入列数:4 请输入非零元个数:5 输入其行号、列号及非零元 ---------第1个非零元--------- 请输入行号:1 请输入列号:1 请输入非零元数据:6 ---------第2个非零元--------- 请输入行号:1 请输入列号:3 请输入非零元数据:9 ---------第3个非零元--------- 请输入行号:2 请输入列号:2 请输入非零元数据:5 ---------第4个非零元--------- 请输入行号:3 请输入列号:4 请输入非零元数据:12 ---------第5个非零元--------- 请输入行号:4 请输入列号:2 请输入非零元数据:16 矩阵t已建立: 6 0 9 0 0 5 0 0 0 0 0 12 0 16 0 0 输入”st”,将其转置并显示: 转置后矩阵t变为: 6 0 0 0 0 5 0 16 9 0 0 0 0 0 12 0 同理,输入”cl”,回车,依次输入以下数据: 5 5 7 1 1 11 1 3 13 2 2 14 2 5 16 3 4 17 4 1 18 5 5 15 可建立如下矩阵: 矩阵l已建立: 11 0 13 0 0 0 14 0 0 16 0 0 0 17 0 18 0 0 0 0 0 0 0 0 15 再输入“cm”回车,依次输入如下数据: 5 5 8 1 2 21 1 4 22 2 1 24 2 3 23 3 5 26 4 2 28 4 3 29 5 5 25 建立如下矩阵: 矩阵m已建立: 0 21 0 22 0 24 0 23 0 0 0 0 0 0 26 0 28 29 0 0 0 0 0 0 25 输入“'l”,回车,”’m”,回车,分别查看l,m的转置: 矩阵l的转置为: 11 0 0 18 0 0 14 0 0 0 13 0 0 0 0 0 0 17 0 0 0 16 0 0 15 矩阵m的转置为: 0 24 0 0 0 21 0 0 28 0 0 23 0 29 0 22 0 0 0 0 0 0 26 0 25 输入“+”查看l+m的和 m与l的和: 11 21 13 22 0 24 14 23 0 16 0 0 0 17 26 18 28 29 0 0 0 0 0 0 40 输入“*”查看l+m的积 m与l的积: 0 231 0 242 338 336 0 322 0 400 0 476 493 0 0 0 378 0 396 0 0 0 0 0 375 输入“sm”,将m转置 转置后矩阵m变为: 0 24 0 0 0 21 0 0 28 0 0 23 0 29 0 22 0 0 0 0 0 0 26 0 25 再次输入“*”和“+”查看它们的和与积 m与l的和: 11 24 13 0 0 21 14 0 28 16 0 23 0 46 0 40 0 0 0 0 0 0 26 0 40 m与l的积: 0 563 0 377 0 294 0 416 392 400 374 0 0 0 0 0 432 0 0 0 0 0 390 0 375 ``` 经检验,运行结果完全正确。 **注:转发请注明出处,以免老师误以为本人抄袭……**


发表评论

必填,公开,这样称呼起来方便~

必填,不会被公开,不必担心~

http://

非必填,公开,目的是方便增进友好访问~

必填,请输入下方图片中的字母或数字,以证明你是人类

看不清楚
必填,最好不要超过500个字符
     ↑返回顶端↑