zoukankan      html  css  js  c++  java
  • (数据结构课程设计)稀疏矩阵运算器

    1.设计内容
      稀疏矩阵是指那些多数元素为零的矩阵。利用“稀疏”特点进行存储和计算可以大大节省存储空间,提高计算准备效率。实现一个能进行稀疏矩阵基本运算的运算器。
    具体功能有:
    (1)以“带行逻辑链接信息”的三元组顺序表示稀疏矩阵,实现两个稀疏矩阵相加、相减、相乘、求逆以及矩阵转置和求矩阵对应行列式值的功能。
    (2)稀疏矩阵的输入形式采用三元组表示,而运算结果的矩阵则以通常的阵列形式列出。
    2. 本设计所采用的数据结构
    稀疏矩阵采用带行逻辑链接信息的三元组顺序存储


    本设计最终代码实现如下(C语言):

    #include<stdio.h>
    #include<math.h>
    #include<stdlib.h>
    #include<conio.h>
    #include<malloc.h>
    #include<string.h>
    #define MAXSIZE 100          /*假设非零元个数的最大值为100*/
    #define MAXMU 25              /*稀疏矩阵最大行列值为25*/
    typedef struct
    {
    	int i,j;                 /*该非零元的行下标和列下标*/
    	int v;
    }Triple;
    typedef struct            /*稀疏矩阵是由三元组的顺序存储*/
    {   int rpos[MAXMU+1];	     /*各行第一个非零元素的位置表*/
    	Triple data[MAXSIZE+1];  /*非零元三元组顺序表,data[0]未使用*/
    	int mu,nu,tu;            /*矩阵的行数,列数和非零元个数*/
    }TSMatrix;
    
    void creat(TSMatrix *T) /*由用户输入创建稀疏矩阵*/
    {
    	int row,num,k;
    	do
    	{
    		system("cls");
    		system("color 4f");
    		printf("
     请输入矩阵!
    ");
    		printf("*********************************
    ");
    		printf(" 请输入稀疏矩阵行数: ");
    		scanf("%d", &T->mu);
    		if (T->mu<0 || T->mu>MAXMU)
    			printf("
     行数超出定义范围,请重新输入!
    ");
    	} while (T->mu<0 || T->mu>MAXMU);
    	do
    	{
    		printf(" 请输入稀疏矩阵列数: ");
    		scanf("%d", &T->nu);
    		if (T->nu<0 || T->nu>MAXMU)
    			printf("
     列数超出定义范围,请重新输入!
    ");
    	} while (T->nu<0 || T->nu>MAXMU);
    	do
    	{
    		printf(" 请输入稀疏矩阵的非零元素个数: ");
    		scanf("%d", &T->tu);
    		if (T->tu>MAXSIZE || (T->tu>T->mu*T->nu))
    			printf("
     非零元素个数超出定义范围,请重新输入!
    ");
    	} while (T->tu>MAXSIZE || (T->tu>T->mu*T->nu));
    	printf("**********************************
    ");
    	printf(" 请按行从小到大依次输入结点信息!
    ");
    	for (k=1; k<=T->tu; k++)
    	{
    		do
    		{
    			printf(" 请按三元组存储输入第%d个非零元素的行数i:", k);
    			scanf("%d", &T->data[k].i);
    			if (!T->data[k].i || T->data[k].i>T->mu)
    				printf("
     输入有误,请重新输入!
    ");
    		} while ((!T->data[k].i || T->data[k].i>T->mu));
    		do
    		{
    			printf(" 请按三元组存储输入第%d个非零元素的列数j:", k);
    			scanf("%d", &T->data[k].j);
    			if (!T->data[k].j || T->data[k].j>T->nu)
    				printf("
     输入有误,请重新输入!
    ");
    		} while ((!T->data[k].j || T->data[k].j>T->nu));
    		do
    		{
    			printf(" 请按三元组存储输入第%d个非零元素的值v:", k);
    			scanf("%d", &T->data[k].v);
    			if (T->data[k].v==0)
    				printf("
     输入有误,请重新输入!
    ");
    		} while (T->data[k].v==0);
    		printf("***********************************
    ");
    	}
    	for(row=1,num=1;row<=T->mu;row++)   /*行逻辑链接信息存储*/
    	{
    		T->rpos[row]=num;
    		while(T->data[num].i==row)
    			num++;
    	}
    	return;
    }
    
    void print(TSMatrix A)   /*输出稀疏矩阵*/
    {
    	int q,n,k,a=0;
        system("cls");
        system("color 4f");
        printf("
    
    经过稀疏矩阵运算器运算,所得结果为:
    ");
        printf("***********************************
    ");
        printf("***********************************
    ");
    	for(n=1;n<=A.mu;n++)
    	{
    	 for(k=1;k<=A.nu;k++)
           {
    		 for(q=1;q<=A.tu;q++)
    			 if(A.data[q].i==n && A.data[q].j==k)
    			 {
    				 printf("	%-3d",A.data[q].v);break;
    			 }
    		 if(q>A.tu)
    			 printf("	%-3d",a);		 
    	   }
    	 printf("
    ");
    	} 
    	printf("***********************************
    ");
    	printf("***********************************
    ");
     }
    
    void add(TSMatrix A,TSMatrix B)   /*加法运算*/
    {
    	system("color 4f");
    	int n,k;
    	if(A.mu!=B.mu || A.nu!=B.nu)
    	{ 
    		printf("
              不满足矩阵相加条件!"); 
            printf("
     需满足两矩阵的行数、列数均对应相等方可进行加法运算!!");
    	}
    	else  
    	{
    		for(n=1;n<=A.tu;n++)
    	         for(k=1;k<=B.tu;k++)   /*将矩阵A的非零元接至B中*/
    				 if(A.data[n].i==B.data[k].i && A.data[n].j==B.data[k].j)
    				 {
    					 A.data[n].v+=B.data[k].v;
    			         B.data[k].v=0;
    				 }
    		for(k=1;k<=B.tu;k++)
    			if(B.data[k].v!=0)
    			{
    				A.data[A.tu+1].i=B.data[k].i;
    				A.data[A.tu+1].j=B.data[k].j;
    				A.data[A.tu+1].v=B.data[k].v;
    				A.tu++;	
    			}
    		print(A);
         }
    }
    
    void sub(TSMatrix A,TSMatrix B)   /*减法运算*/
    {
    	system("color 4f");
    	int n,k;
        if(A.mu!=B.mu || A.nu!=B.nu)
    	{
    		printf("
        不满足矩阵相减条件!"); 
    		printf("
     需要满足两矩阵的行数、列数均对应相等方可进行减法运算!!");
    	}
    	else
    	{
    	    for(n=1;n<=A.tu;n++)
    	        for(k=1;k<=B.tu;k++)   /*将矩阵A的非零元接至B中*/
    				if(A.data[n].i==B.data[k].i && A.data[n].j==B.data[k].j)
    				{
    					A.data[n].v-=B.data[k].v;
    					B.data[k].v=0;
    				}
                for(k=1;k<=B.tu;k++)
    				if(B.data[k].v!=0)
    				{
    					A.data[A.tu+1].i=B.data[k].i;
    				    A.data[A.tu+1].j=B.data[k].j;
    				    A.data[A.tu+1].v=-B.data[k].v;
    				    A.tu++;
    				}
    		print(A);  
    	}
    }
    
    void mult(TSMatrix A,TSMatrix B,TSMatrix *c)   /*乘法运算*/
    {
    	system("color 4f");
    	int arow,tp,i,t;
    	int ccol,p,brow,q;
    	int ctemp[MAXMU+1];
    	if(A.nu!=B.mu)
    	{
    		printf(" 矩阵不满足相乘条件!");
    		return ;
    	}
    	c->mu=A.mu;
    	c->nu=B.nu;
    	c->tu=0;
    	if(A.tu==0||B.tu==0)
    	{
    		printf(" 结果矩阵为零!");
    		return ;
    	}
    	else
    	{
    		for(arow=1;arow<=A.mu;arow++)
    		{
    			for(i=0;i<MAXMU;i++)    /*存储器清零*/
    				ctemp[i]=0;
    			c->rpos[arow]=c->tu+1;
    			if(arow<A.mu)
    				tp=A.rpos[arow+1];
    			else
    				tp=A.tu+1;
    			for(p=A.rpos[arow];p<tp;p++)
    			{
    				brow=A.data[p].j;
    				if(brow<B.mu)
    					t=B.rpos[brow+1];
    				else
    					t=B.tu+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->nu;ccol++)
    				if(ctemp[ccol])
    				{
    					if(++(c->tu)>MAXSIZE)
    					{
    						printf("超出范围!");
    						return ;
    					}
    				    c->data[c->tu].v=ctemp[ccol];
    				    c->data[c->tu].i=arow;
    				    c->data[c->tu].j=ccol;
    				}
    		}
    	}
    	print(*c);
    }
    
    char menu()   /*计算器主界面(菜单)*/
    {
    	char n;
        system("color 4f"); 
    	system("title 稀疏矩阵运算器"); 
        system("cls");
    	system("mode con cols=70 lines=30");
        printf("
    ");
        printf("
                课程设计  ******班                      
    
    
    
    
    
    ");
     
        printf("              ****************************************          
    ");
        printf("              *                                      *          
    ");
        printf("              *         稀 疏 矩 阵 运 算 器         *          
    ");
        printf("              *                                      *          
    ");
        printf("              *             实 现 运 算              *          
    ");
        printf("              *                                      *          
    ");
        printf("              *             1:矩阵相加               *          
    ");
        printf("              *             2:矩阵相減               *          
    ");
        printf("              *             3:矩阵相乘               *          
    ");
        printf("              *             4:矩阵求逆               *          
    ");
    	printf("              *             5:矩阵转置               *          
    ");
        printf("              *             6:行列式值               *          
    ");
    	printf("              *             7:选择退出               *          
    ");
    	printf("              *                                      *          
    ");
        printf("              ****************************************          
    ");
        printf("                        请输入序号进行操作  :)                 
    ");
        printf("                                 ");n=getchar();
    	 
        return n;
    }
    
    void zhuanzhi(TSMatrix A)   /*转置运算*/
    {
    	int p,q,m;
    	TSMatrix B;
    	B.mu=A.nu; /*将原矩阵的行列数及非零元个数赋给新矩阵*/
    	B.nu=A.mu;
    	B.tu=A.tu;
    	if(B.tu)
    	{
    		m=1;
    		for(p=1;p<=A.mu;p++)              /*将原非零元三元组的行列值交换后赋给新三元组,得到转置矩阵*/
    			for(q=1;q<=A.nu;q++)
    			{
    				B.data[m].i=A.data[m].j;
    				B.data[m].j=A.data[m].i;
    				B.data[m].v=A.data[m].v;
    				++m;
    			}
    	}
    	print(B);
    }
    
    int JsMatrix(int s[][MAXMU],int n) /*通过递归求矩阵对应行列式的值*/   
    {
    	int z,j,k,r,total=0;
    	int b[MAXMU][MAXMU];
    	if(n>2)
    	{
    		for(z=0;z<n;z++)
    			{for(j=0;j<n-1;j++)
    				for(k=0;k<n-1;k++)
    					if(k>=z) b[j][k]=s[j+1][k+1];
    					else b[j][k]=s[j+1][k];
    					if(z%2==0) r=s[0][z]*JsMatrix(b,n-1);
    					else r=(-1)*s[0][z]*JsMatrix(b,n-1);
    			total=total+r;
    			}
    	}
    	else if(n==2) total=s[0][0]*s[1][1]-s[0][1]*s[1][0];
    	return total;
    }
    
    void yuzishi(int s[][MAXMU],int b[][MAXMU],int n) /*求矩阵每个元素对应的余子式*/
    {
    	int z,j,k,m,l,g,a[MAXMU][MAXMU];
    	for(z=0;z<n;z++)
    	{
    		l=z;
    		for(j=0;j<n;j++)
    		{	
    			m=j;
    			for(k=0;k<n-1;k++)
    				for(g=0;g<n-1;g++)
    				{
    					if(g>=m&&k<l) a[k][g]=s[k][g+1];
    					else if(k>=l&&g<m)  a[k][g]=s[k+1][g];
    				    else if(k>=l&&g>=m) a[k][g]=s[k+1][g+1];
    				    else   a[k][g]=s[k][g];
    				}	
    			b[z][j]=JsMatrix(a,n-1);/*调用求行列式函数求出余子式*/
    		}
    	}
    }
    
    void qiuni(TSMatrix TM)   /*求逆运算*/
    {
    	system("color 4f");
    	int i,j,n,k;
    	n=TM.mu;
    	float temp;
    	int a[MAXMU][MAXMU];
    	int b[MAXMU][MAXMU];
    	float c[MAXMU][MAXMU];
    	for(i=0;i<n;i++)
    		for(j=0;j<n;j++)
    			a[i][j]=0;
    	for(i=1;i<=TM.tu;i++)
    		a[TM.data[i].i-1][TM.data[i].j-1]=TM.data[i].v;
    	k=JsMatrix(a,n); /*调用求行列式值的函数求出行列式的值*/
    	printf(" 矩阵的行列式的值为:|A|=%d
    ",k);
    	if(k==0)
    		printf(" 行列式的值|A|=0,原矩阵无逆矩阵!");
    	else
    	{
    		yuzishi(a,b,n);
    
    		for(i=0;i<n;i++) /*由余子式得到代数余子式*/
    			for(j=0;j<n;j++)
    				if((i+j)%2!=0 && b[i][j]!=0) 
    					b[i][j]=-b[i][j];
    
    		for(i=0;i<n;i++) /*将代数余子式矩阵转置得到伴随矩阵*/
    			for(j=i+1;j<n;j++)
    			{
    				temp=b[i][j];
    				b[i][j]=b[j][i];
    				b[j][i]=temp;
    			}
    
    		printf(" 伴随矩阵A*为:
    ");
    		for(i=0;i<n;i++) /*输出伴随矩阵*/
    		{
    			printf("
    ");
    			for(j=0;j<n;j++)
    				printf("%6d",b[i][j]);
    			printf("
    ");
    		}
    		for(i=0;i<n;i++)/*伴随矩阵除以行列式的值得到逆矩阵*/
    			for(j=0;j<n;j++)
    				c[i][j]=(float)b[i][j]/k;
    		printf(" 逆矩阵(A*)/|A|为:
    "); 
    		for(i=0;i<n;i++)/*输出逆矩阵*/
    		{
    			printf("
    ");
    				for(j=0;j<n;j++)
    					printf("%1.1f	",c[i][j]);		    
    			printf("
    ");
    		}
    	}
    }
    void hlsz(TSMatrix TM)   /*求逆运算*/
    {
    	system("color 4f");
    	int i,j,n,k;
    	n=TM.mu;
    	float temp;
    	int a[MAXMU][MAXMU];
    	int b[MAXMU][MAXMU];
    	float c[MAXMU][MAXMU];
    	for(i=0;i<n;i++)
    		for(j=0;j<n;j++)
    			a[i][j]=0;
    	for(i=1;i<=TM.tu;i++)
    		a[TM.data[i].i-1][TM.data[i].j-1]=TM.data[i].v;
    	k=JsMatrix(a,n); /*调用求行列式值的函数求出行列式的值*/
    	printf("该稀疏矩阵对应行列式的值为%d",k);
    }
    void main() /*功能主函数*/
    { 
    	TSMatrix A,B,C;
    
    	 for(;;)
    		 switch(menu())
    	 {case '1':creat(&A);
                   creat(&B);
    			   add(A,B);
    			   getch();
    			   break;
          case '2':creat(&A);
                   creat(&B);
    			   sub(A,B);
    			   getch();
    			   break;
          case '3':creat(&A);
                   creat(&B);
    			   mult(A,B,&C);
    			   getch();
    			   break;
    	  case '4':creat(&A);
    		       qiuni(A);
    			   getch();
    			   break;
    	  case '5':creat(&A);
    		       zhuanzhi(A);
    			   getch();
    			   break;
    	  case '6':creat(&A);
    		       hlsz(A);
    			   getch();
    			   break;
          case '7':system("cls");
    			  system("color f2");
    			  printf("计算器已关闭,按任意键退出 :)
    ");
    			  exit(0);
    	 }
    }
    



  • 相关阅读:
    洛谷 P2590 [ZJOI2008]树的统计
    如何让文件夹隐藏起来,保护自己的隐私
    SharePoint入门——创建一个网站
    SharePoint 解决管理员密码修改后各种问题的来袭
    .NET创建一个即是可执行程序又是Windows服务的程序
    C#——WebApi 接口参数传参详解
    C#中对Web.Config、App.Config字符串加密与解密的方法
    邮件服务器常用地址和端口信息
    Unity3d 5.x搭载VS2013使用
    系统性能优化- Session丢失
  • 原文地址:https://www.cnblogs.com/youth-dream/p/7780202.html
Copyright © 2011-2022 走看看