课程设计:用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;idata[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;jdata[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;r1<(2*B->m);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;i<(*C)->len;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;i<(*A)->len;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;col<(A->n);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(k<(a->len)&&(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;i<(*A)->len;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);
}

你可能感兴趣的:(课程设计:用C语言编写的稀疏矩阵运算器(加、减、乘、求逆))