课程设计:用C语言编写的稀疏矩阵运算器(加、减、乘、求逆)
#include
#include
int system(const char *string);
#define maxsize 2000
typedef struct
{
int row;
int col;
int data;
}triple;
typedef struct
{
triple data[maxsize];
int m,n,len;
}matrix;
typedef struct
{
int row;
int col;
float data;
}triple_f;
typedef struct
{
triple_f data[maxsize];
int m,n,len;
}matrix_f;
matrix_f *Init_f()
{
int i=0;
matrix_f *A;
A=(matrix_f*)malloc(sizeof(matrix_f));
A->len=0;
A->m=0;
A->n=0;
for(i=0;i
{
A->data[i].col=0;
A->data[i].row=0;
A->data[i].data=0;
}
return A;
}
matrix *Init()
{
int j=0;
matrix *A;
A=(matrix*)malloc(sizeof(matrix));
A->len=0;
A->m=0;
A->n=0;
for(j=0;j
{
A->data[j].col=0;
A->data[j].row=0;
A->data[j].data=0;
}
return A;
}
void print_menu()
{
char ch1='=';
int i;
for(i=0;i<80;i++)
printf("%c",ch1);
}
void qiuni(matrix_f *A,matrix_f **C)
{
/*参数声明*/
int i=0,j=0,m=0,row=0,col=0,r1,k,tz=0,tem_row,tem_col,l;
float n1,n2,t,x,n3,sum;
matrix_f *B;
/*变量运算*/
B=Init_f();
/*创建矩阵AI*//*这部分已完成,下面部分禁止修改*/
m=0;j=0;
B->m=A->m; B->n=2*(A->n); B->len=(B->m)*(B->n);
tem_row=0; tem_col=0;
for(i=0;ilen;i++)
{
B->data[i].data=0;
B->data[i].col=tem_col;
B->data[i].row=tem_row;
tem_col++;
if(tem_col==B->n)
{
tem_col=0;
tem_row++;
}
}
for(i=0;ilen;i++)
for(j=0;jlen;j++)
if(B->data[j].row==A->data[i].row&&B->data[j].col==A->data[i].col)
B->data[j].data=A->data[i].data;
j=0;
for(i=0;im;i++)
{
B->data[j*(B->n)+i+B->m].data=1;
j++;
}
/*变换矩阵AI*/
row=0;col=0;i=0;j=0;n1=1.0;n2=1.0;
r1=0;k=0;t=1.0; l=0;x=0;
for(col=0;colm;col++)
{
for(row=0;rowm;row++)
{
if(row!=col)
{
for(i=0;ilen;i++)
if(B->data[i].row==row&&B->data[i].col==col)
{n1=B->data[i].data;break;}
for(j=0;jlen;j++)
if(B->data[j].row==col&&B->data[j].col==col)
{n2=B->data[j].data;break;}
t=n1/n2;
for(r1=0;r1m);r1++)
{
for(k=0;klen;k++)
if(B->data[k].row==col&&B->data[k].col==r1)
{n3=B->data[k].data;break;}
x=n3*t;
for(l=0;llen;l++)
if(B->data[l].row==row&&B->data[l].col==r1)
{B->data[l].data=B->data[l].data-x;break;}
}
}
}
}
row=0;j=0;n1=0;col=0;i=0;
for(row=0;rowm;row++)
{
for(j=0;jlen;j++)
if(B->data[j].row==row&&B->data[j].col==row)
{n1=B->data[j].data;break;}
for(col=0;coln;col++)
for(i=0;ilen;i++)
if(B->data[i].row==row&&B->data[i].col==col)
{B->data[i].data=(B->data[i].data)/n1;break;}
}
row=0;col=0;sum=1;tem_row=0;tem_col=0;
for(row=0;rowm;row++)
{
for(i=0;ilen;i++)
{
if(B->data[i].row==row&&B->data[i].col==row)
sum=sum*(B->data[i].data);
}
}
if(sum==0)
printf("您所输入的矩阵没有逆矩阵!\n");
else
{
(*C)->len=B->len/2;
(*C)->m=B->m;
(*C)->n=B->m;
for(i=0;ilen;i++)
{
(*C)->data[i].data=B->data[i+(tem_row+1)*B->m].data;
(*C)->data[i].row=B->data[i+(tem_row+1)*B->m].row;
(*C)->data[i].col=B->data[i+(tem_row+1)*B->m].col;
tem_col++;
if(tem_col==(*C)->m)
{
tem_col=0;
tem_row++;
}
}
}
}
void print_menu2()
{
print_menu();
printf("= 1.创建矩阵A =");
printf("= 2.创建矩阵B =");
printf("= 3.创建矩阵C【求逆矩阵专用】 =");
printf("= 4.矩阵A + 矩阵B =");
printf("= 5.矩阵A - 矩阵B =");
printf("= 6.矩阵A * 矩阵B =");
printf("= 7.求矩阵A的逆矩阵 =");
printf("= 8.退出 =");
print_menu();
printf("请选择要进行的操作:");
}
void Creat(matrix **A)
{
int i=0;
int n1,n2;
int j=0;
FILE *get;
char getname[20];
int m=0;
int row=0;
int col=0;
FILE *in1;
char ch1;
int g=0;
FILE *in2;
char ch2;
int p=0;
int z=0;
print_menu();
printf("= 1.手动创建 =");
printf("= 2.从文件载入 =");
print_menu();
printf("请选择矩阵创建方式:");
scanf("%d",&j);
switch(j)
{
case 1:
{system("cls");
printf("=========================请输入矩阵的行列数及非零元个数=========================");
scanf("%d%d%d",&(*A)->m,&(*A)->n,&(*A)->len);
for(i=0;ilen;i++)
{
printf("请输入第 %d 个非零元素的行: ",i+1);
scanf("%d",&n1);
(*A)->data[i].row=(n1-1);
printf("请输入第 %d 个非零元素的列: ",i+1);
scanf("%d",&n2);
(*A)->data[i].col=(n2-1);
printf("请输入第 %d 个非零元素的值: ",i+1);
scanf("%d",&(*A)->data[i].data);
printf("\n");
}
printf("==================================矩阵创建完成==================================");
break;
}
case 2:
{
system("cls");
printf("==============================请输入要打开的文件名==============================");
printf(" ");
scanf("%s",&getname);
if((get=fopen(getname,"r"))==NULL)
{
printf("打开文件出错!请检查文件是否存在。\n");
system("pause");
exit(0);
}
else
printf("打开完成!\n");
printf("正在从文件中载入矩阵...\n");
in1=fopen(getname,"r");
while(!feof(in1))
{
ch1=fgetc(in1);
if(ch1=='\n')
g++;
}
in2=fopen(getname,"r");
while(!feof(in2))
{
ch2=fgetc(in2);
if(ch2==' ')
p++;
else if(ch2=='\n')
break;
}
p=p+1; g=g+1;
printf("矩阵载入成功!\n");
printf("\n文本行数为:%d\n",g);
printf("文本列数为:%d\n",p);
printf("非零元素信息如下:\n");
while(!feof(get))
{
fscanf(get,"%d",&n1);
if(n1!=0)
{
(*A)->data[m].data=n1;
(*A)->data[m].row=row;
(*A)->data[m].col=col;
printf("行:%d ",(*A)->data[m].row+1);
printf("列:%d ",(*A)->data[m].col+1);
printf("值:%d \n",(*A)->data[m].data);
m++;
col++;
z++;
if(col==p)
{col=0; row++;}
}
else if(n1==0)
{
col++;
if(col==p)
{col=0;row++;}
}
}
(*A)->m=g;
(*A)->n=p;
(*A)->len=z;
}
}
}
void print(matrix *A)
{
FILE *put;
char putname[20];
int i=0;
int row;
int col;
int j;
char ch1='0';
char ch2=' ';
printf("是否将结果显示在屏幕上?(建议大矩阵保存在文件中。)\t是[0]/否[1]\n");
scanf("%d",&j);
switch(j)
{
case 0:
{system("cls");
for(row=0;rowm;row++)
{
for(col=0;coln);col++)
{
if(A->data[i].col==col&&A->data[i].row==row)
{
printf("%d ",A->data[i].data);
i++;
}
else printf("0 ");
}
printf("\n");
}
break;
}
case 1:
{
system("cls");
printf("请输入要保存的文件名:");
scanf("%s",&putname);
/*写入文件部分*/
if((put=fopen(putname,"w"))==NULL)
{
printf("无法打开!");
exit(0);
}
else
printf("\a创建或打开文件 %s 成功!\n",putname);
{
for(row=0;rowm;row++)
{
for(col=0;coln;col++)
{
if(A->data[i].col==col&&A->data[i].row==row)
{fprintf(put,"%d",A->data[i].data);fputc(ch2,put);i++;}
else {fputc(ch1,put);fputc(ch2,put);}
}
fputc(10,put);
}
}
fclose(put);
printf("已保存!\n");
break;
}
}
}
int value(matrix *a,int i,int j) //矩阵相乘时 取出一行或一列
{
int k=0;
while(klen)&&(a->data[k].row!=i||a->data[k].col!=j))
k++;
if(klen)
return a->data[k].data;
else
return 0;
}
void arr(matrix *a,matrix *b,matrix **c)
{
int i=0,j=0,k=0,p=0;
int tem;
if(a->m!=b->n)
{
printf("您输入的两个矩阵不满足相乘条件!");
system("pause");
exit(0);
}
for(i=0;in;i++)
{
for(j=0;jm;j++)
{
tem=0;
for(k=0;km;k++)
{
tem=tem+value(a,i,k)*value(b,k,j);
}
if(tem!=0)
{
(*c)->data[p].row=i;
(*c)->data[p].col=j;
(*c)->data[p].data=tem;
p++;
}
}
(*c)->n=a->n;
(*c)->m=a->m;
(*c)->len=p;
}
}
void add(matrix *a,matrix *b,matrix **c)
{
if(a->m==b->m&&a->n==b->n)
{
int i=0,j=0,k=0;
(*c)->m=a->m;
(*c)->n=a->n;
while(ilen||jlen)
{
if(i==a->len&&jlen)
{
(*c)->data[k].col=b->data[j].col;
(*c)->data[k].row=b->data[j].row;
(*c)->data[k++].data=b->data[j].data;
(*c)->len++;
j++;
}
else if(ilen&&j==b->len)
{
(*c)->data[k].col=a->data[i].col;
(*c)->data[k].row=a->data[i].row;
(*c)->data[k++].data=a->data[i].data;
(*c)->len++;
i++;
}
else
{
if(a->data[i].row>b->data[j].row)
{
(*c)->data[k].col=b->data[j].col;
(*c)->data[k].row=b->data[j].row;
(*c)->data[k++].data=b->data[j].data;
(*c)->len++;
j++;
}
else if(a->data[i].rowdata[j].row)
{
(*c)->data[k].col=a->data[i].col;
(*c)->data[k].row=a->data[i].row;
(*c)->data[k++].data=a->data[i].data;
(*c)->len++;
i++;
}
else
{
if(a->data[i].col==b->data[j].col)
{
if(a->data[i].data+b->data[j].data!=0)
{
(*c)->data[k].col=a->data[i].col;
(*c)->data[k].row=a->data[i].row;
(*c)->data[k++].data=a->data[i].data+b->data[j].data;
(*c)->len++;
}
i++;
j++;
}
else if(a->data[i].col>b->data[j].col)
{
(*c)->data[k].col=b->data[j].col;
(*c)->data[k].row=b->data[j].row;
(*c)->data[k++].data=b->data[j].data;
(*c)->len++;
j++;
}
else if(a->data[i].coldata[j].col)
{
(*c)->data[k].col=a->data[i].col;
(*c)->data[k].row=a->data[i].row;
(*c)->data[k++].data=a->data[i].data;
(*c)->len++;
i++;
}
}
}
}
}
else
{
printf("您输入的两个矩阵不满足运算条件!\n");
system("pause");
}
}
void sub(matrix *A,matrix *B,matrix **C)
{
int k=0;
for(k=0;klen;k++) B->data[k].data=-B->data[k].data;
if(A->m==B->m&&A->n==B->n) add(A,B,C);
else
{
for(k=0;klen;k++)
B->data[k].data=-B->data[k].data;
system("pause");
}
}
void Creat_f(matrix_f **A)
{
int i=0;
float n1;
int n3,n4;
int j=0;
FILE *get;
char getname[20];
int m=0;
int row=0;
int col=0;
FILE *in1;
char ch1;
int g=0;
FILE *in2;
char ch2;
int p=0;
int z=0;
print_menu();
printf("= 1.手动创建 =");
printf("= 2.从文件载入 =");
print_menu();
printf("请选择矩阵创建方式:");
scanf("%d",&j);
switch(j)
{
case 1:
{system("cls");
printf("=========================请输入矩阵的行列数及非零元个数=========================");
scanf("%d%d%d",&(*A)->m,&(*A)->n,&(*A)->len);
for(i=0;ilen;i++)
{
printf("请输入第 %d 个非零元素的行: ",i+1);
scanf("%d",&n3);
(*A)->data[i].row=(n3-1);
printf("请输入第 %d 个非零元素的列: ",i+1);
scanf("%d",&n4);
(*A)->data[i].col=(n4-1);
printf("请输入第 %d 个非零元素的值: ",i+1);
scanf("%f",&(*A)->data[i].data);
printf("\n");
}
printf("==================================矩阵创建完成==================================");
break;
}
case 2:
{
system("cls");
printf("==============================请输入要打开的文件名==============================");
printf(" ");
scanf("%s",&getname);
if((get=fopen(getname,"r"))==NULL)
{
printf("打开文件出错!请检查文件是否存在。\n");
system("pause");
exit(0);
}
else
printf("打开完成!\n");
printf("正在从文件中载入矩阵...\n");
in1=fopen(getname,"r");
while(!feof(in1))
{
ch1=fgetc(in1);
if(ch1=='\n')
g++;
}
in2=fopen(getname,"r");
while(!feof(in2))
{
ch2=fgetc(in2);
if(ch2==' ')
p++;
else if(ch2=='\n')
break;
}
p=p+1; g=g+1;
printf("矩阵载入成功!\n");
printf("\n文本行数为:%d\n",g);
printf("文本列数为:%d\n",p);
printf("非零元素信息如下:\n");
while(!feof(get))
{
fscanf(get,"%f",&n1);
if(n1!=0)
{
(*A)->data[m].data=n1;
(*A)->data[m].row=row;
(*A)->data[m].col=col;
printf("行:%d ",(*A)->data[m].row+1);
printf("列:%d ",(*A)->data[m].col+1);
printf("值:%0.1f \n",(*A)->data[m].data); //检测载入是否成功。
m++;
col++;
z++;
if(col==p)
{col=0; row++;}
}
else if(n1==0)
{
col++;
if(col==p)
{col=0;row++;}
}
}
(*A)->m=g;
(*A)->n=p;
(*A)->len=z;
}
}
}
void print_f(matrix_f *A)
{
FILE *put;
char putname[20];
int i=0;
int j;
char ch1='0';
char ch2=' ';
int t_row=0,t_col=0;
printf("是否将结果显示在屏幕上?(建议大矩阵保存在文件中。)\t是[0]/否[1]\n");
scanf("%d",&j);
switch(j)
{
case 0:
{system("cls");
for(i=0;ilen;i++)
{
printf("%0.1f ",A->data[i].data);
t_col++;
if(t_col==A->n)
{
printf("\n");
t_col=0;
}
}
break;
}
case 1:
{
system("cls");
printf("请输入要保存的文件名:");
scanf("%s",&putname);
/*写入文件部分*/
if((put=fopen(putname,"w"))==NULL)
{
printf("无法打开!");
exit(0);
}
else
printf("\a创建或打开文件 %s 成功!\n",putname);
{
for(i=0;ilen;i++)
{
fprintf(put,"%0.1f",A->data[i].data);
fputc(ch2,put);fputc(ch2,put);fputc(ch2,put);
t_col++;
if(t_col==A->n)
{
fputc(10,put);
t_col=0;
}
}
}
fclose(put);
printf("已保存!\n");
break;
}
}
}
void main()
{
int num;
matrix *A;
matrix *B;
matrix *C;
matrix_f *S;
matrix_f *T;
A=Init();
B=Init();
C=Init();
S=Init_f();
T=Init_f();
print_menu2();
scanf("%d",&num);
while(num<=8)
{
switch(num)
{
case 1:
{
system("cls");
printf("创建矩阵A...\n");
Creat(&A);
system("pause");
system("cls");
print_menu2();
break;
}
case 2:
{
system("cls");
printf("创建矩阵B...\n");
Creat(&B);
system("pause");
system("cls");
print_menu2();
break;
}
case 3:
{
system("cls");
printf("创建矩阵S...\n");
Creat_f(&S);
system("pause");
system("cls");
print_menu2();
break;
}
case 4:
{
printf("正在执行加法运算...\n");
add(A,B,&C);
print(C);
system("pause");
system("cls");
print_menu2();
break;
}
case 5:
{
printf("正在执行减法运算...\n");
sub(A,B,&C);
print(C);
system("pause");
system("cls");
print_menu2();
break;
}
case 6:
{
printf("正在执行乘法运算...\n");
arr(A,B,&C);
print(C);
system("pause");
system("cls");
print_menu2();
break;
}
case 7:
{
if(A->m!=A->n)
printf("矩阵行数不等于列数,没有逆矩阵!\n");
else
{
printf("正在执行求逆运算...\n");
qiuni(S,&T);
print_f(T);
system("pause");
system("cls");
print_menu2();
}
break;
}
case 8:
{
exit( 0);
break;
}
}//switch结束
scanf("%d",&num);
}//while结束
scanf("%d",&num);
}