问题描述:
有输入界面(图形或文字界面都可),能区分加法、减法、乘法和转置;能处理任意输入的典型数据和进行出错数据处理(例如乘法,当第一个矩阵的列数不等于第二个矩阵的行数时);必须采用三元组作存储结构,不能采用数组等形式;输出要求用矩阵的形式输出(即习题集136页的形式),当第一个矩阵的行数不等于第二个矩阵的行数时,注意如第三个乘法的形式输出
******************************************************************************************
#include<stdio.h>
#define maxsize 100
typedef struct
{
int i,j; //该非零元的行和列
int v; //该非零元的值
}triple;
typedef struct
{
triple data[maxsize]; //非零元三元组表,data[0]未用
int rpos[maxsize];
int m,n,t; //矩阵的行数,列数和非零元个数
}tripletable;
void convert() //矩阵的转置
{
int k;
tripletable A,B;
printf("输入稀疏矩阵A的行数,列数和非零元个数:");
scanf("%d %d %d",&A.m,&A.n,&A.t);
for(k=1;k<=A.t;k++)
{
printf("输入第%d个非0元素的行数,列数和值:",k);
scanf("%d %d %d",&A.data[k].i,&A.data[k].j,&A.data[k].v);
}
B.m=A.m;B.n=A.n;B.t=A.t;
if(B.t)
{
int q=1,col;
for(col=1;col<=A.n;++col)
for(int p=1;p<=A.t;++p)
if(A.data[p].j==col)
{
B.data[q].i=A.data[p].j;
B.data[q].j=A.data[p].i;
B.data[q].v=A.data[p].v;
++q;
}
}
int shuru[100][100]={0};
for(k=1;k<=B.t;k++)
{
shuru[B.data[k].j][B.data[k].i]=B.data[k].v;
}
printf("输入为:/n");
for(k=1;k<=B.m;k++)
{
for(int l=1;l<=B.n;l++)
printf("%d ",shuru[k][l]);
printf("/n");
}
int result[100][100]={0};
for(k=1;k<=B.t;k++)
{
result[B.data[k].i][B.data[k].j]=B.data[k].v;
}
printf("结果为:/n");
for(k=1;k<=B.n;k++)
{
for(int l=1;l<=B.m;l++)
printf("%d ",result[k][l]);
printf("/n");
}
}
void add() //矩阵的加法
{
int k;
tripletable A,B;
printf("输入稀疏矩阵A的行数,列数和非零元个数:");
scanf("%d %d %d",&A.m,&A.n,&A.t);
for(k=1;k<=A.t;k++)
{
printf("输入第%d个非0元素的行数,列数和值:",k);
scanf("%d %d %d",&A.data[k].i,&A.data[k].j,&A.data[k].v);
}
printf("输入稀疏矩阵B的行数,列数和非零元个数:");
scanf("%d %d %d",&B.m,&B.n,&B.t);
for(k=1;k<=B.t;k++)
{
printf("输入第%d个非0元素的行数,列数和值:",k);
scanf("%d %d %d",&B.data[k].i,&B.data[k].j,&B.data[k].v);
}
if(A.m!=B.m||A.n!=B.n)
{
printf("输入错误:A与B的行数或列数不相同,请重新输入/n");
return;
}
int a[100][100]={0};
for(k=1;k<=A.t;k++)
{
a[A.data[k].i][A.data[k].j]=A.data[k].v;
}
printf("A输入为:/n");
for(k=1;k<=A.m;k++)
{
for(int l=1;l<=A.n;l++)
printf("%d ",a[k][l]);
printf("/n");
}
int b[100][100]={0};
for(k=1;k<=B.t;k++)
{
b[B.data[k].i][B.data[k].j]=B.data[k].v;
}
printf("B输入为:/n");
for(k=1;k<=B.m;k++)
{
for(int l=1;l<=B.n;l++)
printf("%d ",b[k][l]);
printf("/n");
}
int c[100][100]={0};
for(k=1;k<=A.m;k++)
{
for(int l=1;l<=A.n;l++)
{
c[k][l]=a[k][l]+b[k][l];
}
}
printf("加法结果C为:/n");
for(k=1;k<=A.m;k++)
{
for(int l=1;l<=A.n;l++)
printf("%d ",c[k][l]);
printf("/n");
}
}
void jian() //矩阵的减法
{
int k;
tripletable A,B;
printf("输入稀疏矩阵A的行数,列数和非零元个数:");
scanf("%d %d %d",&A.m,&A.n,&A.t);
for(k=1;k<=A.t;k++)
{
printf("输入第%d个非0元素的行数,列数和值:",k);
scanf("%d %d %d",&A.data[k].i,&A.data[k].j,&A.data[k].v);
}
printf("输入稀疏矩阵B的行数,列数和非零元个数:");
scanf("%d %d %d",&B.m,&B.n,&B.t);
for(k=1;k<=B.t;k++)
{
printf("输入第%d个非0元素的行数,列数和值:",k);
scanf("%d %d %d",&B.data[k].i,&B.data[k].j,&B.data[k].v);
}
if(A.m!=B.m||A.n!=B.n)
{
printf("输入错误:A与B的行数或列数不相同,请重新输入/n");
return;
}
int a[100][100]={0};
for(k=1;k<=A.t;k++)
{
a[A.data[k].i][A.data[k].j]=A.data[k].v;
}
printf("A输入为:/n");
for(k=1;k<=B.m;k++)
{
for(int l=1;l<=A.n;l++)
printf("%d ",a[k][l]);
printf("/n");
}
int b[100][100]={0};
for(k=1;k<=B.t;k++)
{
b[B.data[k].i][B.data[k].j]=B.data[k].v;
}
printf("B输入为:/n");
for(k=1;k<=B.m;k++)
{
for(int l=1;l<=B.n;l++)
printf("%d ",b[k][l]);
printf("/n");
}
int c[100][100]={0};
for(k=1;k<=A.m;k++)
{
for(int l=1;l<=A.n;l++)
{
c[k][l]=a[k][l]-b[k][l];
}
}
printf("减法结果C为:/n");
for(k=1;k<=A.m;k++)
{
for(int l=1;l<=A.n;l++)
printf("%d ",c[k][l]);
printf("/n");
}
}
void multi() //矩阵的乘法
{
int k;
tripletable A,B,C;
printf("输入稀疏矩阵A的行数,列数和非零元个数:");
scanf("%d %d %d",&A.m,&A.n,&A.t);
for(k=1;k<=A.t;k++)
{
printf("输入第%d个非0元素的行数,列数和值:",k);
scanf("%d %d %d",&A.data[k].i,&A.data[k].j,&A.data[k].v);
}
int row=1;
for(k=1;k<=A.t;k++)
{
while(row<=A.data[k].i)
{
A.rpos[row++]=k;
}
}
while(row<=A.m)A.rpos[row++]=A.t+1;
printf("输入稀疏矩阵B的行数,列数和非零元个数:");
scanf("%d %d %d",&B.m,&B.n,&B.t);
for(k=1;k<=B.t;k++)
{
printf("输入第%d个非0元素的行数,列数和值:",k);
scanf("%d %d %d",&B.data[k].i,&B.data[k].j,&B.data[k].v);
}
row=1;
for(k=1;k<=B.t;k++)
{
while(row<=B.data[k].i)
{
B.rpos[row++]=k;
}
}
while(row<=B.m)B.rpos[row++]=B.t+1;
if(A.n!=B.m)
{
printf("输入错误:A的列数不等于B的行数,请重新输入/n");
return;
}
C.m=A.m;C.n=B.n;C.t=0;
int arow,p,q,ccol,t,tp;
if(A.t*B.t!=0)
{
for(arow=1;arow<=A.m;++arow)
{
int ctemp[maxsize]={0};
C.rpos[arow]=C.t+1;
if(arow<A.m){tp=A.rpos[arow+1];}
else{tp=A.t+1;}
for(p=A.rpos[arow];p<tp;++p)
{
int brow=A.data[p].j;
if(brow<B.m){t=B.rpos[brow+1];}
else{t=B.t+1;}
for(q=B.rpos[brow];q<t;++q)
{
ccol=B.data[q].j;
ctemp[ccol]+=A.data[p].v*B.data[q].v;
}
}
for(ccol=1;ccol<=C.n;++ccol)
{
if(ctemp[ccol])
{
if(++C.t>maxsize)return;
C.data[C.t].i=arow;
C.data[C.t].j=ccol;
C.data[C.t].v=ctemp[ccol];
}
}
}
}
int a[100][100]={0};
for(k=1;k<=A.t;k++)
{
a[A.data[k].i][A.data[k].j]=A.data[k].v;
}
printf("A输入为:/n");
for(k=1;k<=A.m;k++)
{
for(int l=1;l<=A.n;l++)
printf("%d ",a[k][l]);
printf("/n");
}
int b[100][100]={0};
for(k=1;k<=B.t;k++)
{
b[B.data[k].i][B.data[k].j]=B.data[k].v;
}
printf("B输入为:/n");
for(k=1;k<=B.m;k++)
{
for(int l=1;l<=B.n;l++)
printf("%d ",b[k][l]);
printf("/n");
}
int c[100][100]={0};
for(k=1;k<=C.t;k++)
{
c[C.data[k].i][C.data[k].j]=C.data[k].v;
}
printf("乘法结果C为:/n");
for(k=1;k<=C.m;k++)
{
for(int l=1;l<=C.n;l++)
printf("%d ",c[k][l]);
printf("/n");
}
}
void main()
{
printf("============= 菜 单 ==============/n");
printf(" 1 矩阵转置/n");
printf(" 2 矩阵加法/n");
printf(" 3 矩阵减法/n");
printf(" 4 矩阵乘法/n");
printf("======================================/n/n");
loop: printf("请选择相应操作的序号:");
int y;
scanf("%d",&y);
switch(y)
{
case 1: convert();
printf("/n");
goto loop;
case 2: add();
printf("/n");
goto loop;
case 3: jian();
printf("/n");
goto loop;
case 4: multi();
printf("/n");
goto loop;
}
}
****************************************************************************************