• 稀疏矩阵三元存储下的计算器


    又是一个实验题:三元数组存储稀疏矩阵,同时实现基本的加法,减法,乘法,求逆

                 思路:

                             首先规范好输入情况

                             明确三元数组的数据结构和输入特征(   行优先输入 

                                                                                       )

                             

                              将稀疏矩阵建立成三元数组和三元数组转化输出

                              数组的加法,减法(

                                                             根据输入的行与列来判断是否可以进行 

                                                             最后的运算结果仍是稀疏矩阵 

                                                              输出结果为矩阵

                                                             )

       思路实现

           

                             明确三元数组的数据结构和输入特征(   行优先输入 

                                                                                       )

                 

    typedef struct 
    {
        int row;
        int col;
        ElementType value;
    }Triple;
    
    typedef struct 
    {
        Triple data[MAXSIZE];
        int rows,cols,nums;//非零起
    }TSMatrix;
    

      

                              将稀疏矩阵建立成三元数组和三元数组转化输出

    PtrTSMatrix CreatMatrix( void )
    {
    
        int count = 0;
         PtrTSMatrix Matrix;
        Matrix  = ( PtrTSMatrix )malloc( sizeof( TSMatrix ) );
         if( Matrix == NULL )
         {
             printf("Not Space
     ");
             exit( 0 );
         }
    
         printf("输入行与列
    ");
         scanf("%d%d",&Matrix->rows,&Matrix->cols);
    
         printf("输入矩阵的元素的行,列,值( -1 结束 ,行优先)
    ");
         scanf("%d%d%d",&Matrix->data[count].row,&Matrix->data[count].col,&Matrix->data[count].value);
         while( Matrix->data[count].row != -1 )
         {
             count++;
             scanf("%d%d%d",&Matrix->data[count].row,&Matrix->data[count].col,&Matrix->data[count].value);
             if( Matrix->data[count].row < Matrix->data[count-1].row && Matrix->data[count].row!=-1 )
            {
                printf("未按行输出:
    ");
                getchar();
                exit(0);
            }//if
         }//while
        Matrix->nums = count;
    
         return Matrix;
    
    }/* CreatMatrix */
    
    /* print the matrix Matrix by using matrix */
    void PrintMatrix( PtrTSMatrix Matrix )
    {
          int i,j;
          int count = 0;
          
          for( i=0; i<Matrix->rows; i++ )
          {
              for( j=0; j<Matrix->cols; j++ )
              {
                  if( count<Matrix->nums && i==Matrix->data[count].row-1 && j==Matrix->data[count].col-1 )
                  {
                      printf("%2d",Matrix->data[count].value);
                      count++;
                  }
                  else
                  {
                      printf("%2d",0);
                  }//if-else
              }//for
              printf("
    ");
          }//for
    }/* PrintMatrix */
    
    PtrTSMatrix CreatMatrix( void )
    {
    
        int count = 0;
         PtrTSMatrix Matrix;
        Matrix  = ( PtrTSMatrix )malloc( sizeof( TSMatrix ) );
         if( Matrix == NULL )
         {
             printf("Not Space
     ");
             exit( 0 );
         }
    
         printf("输入行与列
    ");
         scanf("%d%d",&Matrix->rows,&Matrix->cols);
    
         printf("输入矩阵的元素的行,列,值( -1 结束 ,行优先)
    ");
         scanf("%d%d%d",&Matrix->data[count].row,&Matrix->data[count].col,&Matrix->data[count].value);
         while( Matrix->data[count].row != -1 )
         {
             count++;
             scanf("%d%d%d",&Matrix->data[count].row,&Matrix->data[count].col,&Matrix->data[count].value);
             if( Matrix->data[count].row < Matrix->data[count-1].row && Matrix->data[count].row!=-1 )
            {
                printf("未按行输出:
    ");
                getchar();
                exit(0);
            }//if
         }//while
        Matrix->nums = count;
    
         return Matrix;
    
    }/* CreatMatrix */

                              数组的加法,减法(

                                                             根据输入的行与列来判断是否可以进行 

                                                             最后的运算结果仍是稀疏矩阵 

                                                            )

         一般人最先想到的是两个for循环吧,那么算法的效率为 O( M *N ),我将算法稍稍改进了一下,优化到了 O(M+N ),具体思路如下

    1 1
    2 2 2
    3 3 3

     x

     vaule
         

     类似上面那个三元组,在一个矩阵中想要确认位置需要x,y两个数据,实际上我可以把它回归到它在内存中存储得形式,即是线性存储,每一元素有唯一得一个对应值(假设矩阵为3×3),这样在就可以在一次循环中比较了

    1 1
    5 2
    9 3
    flag  vaule 
       

                           

                  while( 没有一个三元组被遍历完 )

                   {

                              if(俩个三元组位置相同)

                              {

                                     将两个三元组得位置信息和和传递给新的三元组

                                     两个三元组都向后移一位

                             }

                            elseif(  其中一个三元组的元素在另一个之前 )

                            {

                                   将位于前面得元素的位置信息和值传给新得三元组

                                   向后移一位

                              }

                  } 

    /* Plus A and B ,return C */
    PtrTSMatrix AddMatrix( PtrTSMatrix A, PtrTSMatrix B )
    {
        int i=0,j=0;//标记追逐 A  B 
        PtrTSMatrix C;//存放和
    
       if( A->rows!=B->rows || A->cols!=B->cols )
       {
           return NULL;
       }
       
       C = ( PtrTSMatrix )malloc(sizeof( TSMatrix ));
       C->rows = A->rows;
       C->cols = A->cols;
       C->nums = -1; //初始化
       
       while( i<A->nums && j<B->nums )
       {
           if( A->data[i].row*A->cols+A->data[i].col == B->data[j].row*B->cols+B->data[j].col )
           {
               if( A->data[i].value+B->data[j].value != 0 )
               {
                 C->nums++;
                 C->data[C->nums].col = A->data[i].col;
                 C->data[C->nums].row = A->data[i].row;
                 C->data[C->nums].value = A->data[i].value+B->data[j].value;
               }
               i++;
               j++;//标记后移
           }
           else if( A->data[i].row*A->cols+A->data[i].col < B->data[j].row*B->cols+B->data[j].col )
           {
                 C->nums++;
                 C->data[C->nums].col = A->data[i].col;
                 C->data[C->nums].row = A->data[i].row;
                 C->data[C->nums].value = A->data[i].value;
                 i++;
           }
           else
           {
                 C->nums++;
                 C->data[C->nums].col = B->data[j].col;
                 C->data[C->nums].row = B->data[j].row;
                 C->data[C->nums].value = B->data[j].value;
                 j++;
           }//if-else
    
       }//while,
    
       if( i == A->nums )
       {
           while( j < B->nums )
           {
                 C->nums++;
                 C->data[C->nums].col = B->data[j].col;
                 C->data[C->nums].row = B->data[j].row;
                 C->data[C->nums].value = B->data[j].value;
                 j++;
           }
       }
       else 
       {
           while( i < A->nums )
           {
                 C->nums++;
                 C->data[C->nums].col = A->data[i].col;
                 C->data[C->nums].row = A->data[i].row;
                 C->data[C->nums].value = A->data[i].value;
                 i++;
           }
       }//if-else
    
       C->nums++;
    
       return C;
    }//AddMatrix
    

        矩阵乘法的实现:

              原文链接  (详细的解释了原理和B矩阵的两个辅助矩阵构造,但对于算法的实现没有详讲)

             总得来说,在稀疏矩阵中,C=A乘B是对应行和对应列中非零值的事,例如在A 中  i  行中的第一个非零值 A[i][j],可以和它相乘的只有B的 j 行的非零值B[j][k],而且相乘结果还是放在C[i][k]中,这样把A中的非零值都与

           如果给你一张纸来计算A×B,你肯定会先是A的第一行和B的第一列相乘,放在C[0][0]的位置,之后是和B的第二列相乘,放在C[0][1]中,当B的列算到头后,再从A的第二行开始,是吧?但要让计算机对三元组这样操作显然不行,因为你很难确定B三元组的任意一列(当然你要转置,我自然不说什么)。

    那么该怎么做呢? 

         A 0 1 0 1      B 1 0 0      C = ?            

            0 0 1 0         3 2 0

                                     0 1 0

                                     0 0 2                                        

     首先从A中取的第一个值,这个值是 [ 1 2 1 ]([]内的值分别表示其x,y,vaule),那么在整个乘法过程中能和这个值相乘的也只有B中的第二行的[ 2  1 3 ] ,[ 2 2 2]

    并且是放在C的第一行中的不同列的。那么能这么干嘛

    (1).从A三元组中按顺序取一值 [ x  y  z ],那么找到对应的B的y 

      

    PtrTSMatrix AddMatrix( PtrTSMatrix A, PtrTSMatrix B )
    {
    	int i=0,j=0;//标记追逐 A  B 
    	PtrTSMatrix C;//存放和
    
       if( A->rows!=B->rows || A->cols!=B->cols )
       {
    	   return NULL;
       }
       
       C = ( PtrTSMatrix )malloc(sizeof( TSMatrix ));
       C->rows = A->rows;
       C->cols = A->cols;
       C->nums = -1; //初始化
       
       while( i<A->nums && j<B->nums )
       {
    	   if( A->data[i].row*A->cols+A->data[i].col == B->data[j].row*B->cols+B->data[j].col )
    	   {
    		   if( A->data[i].value+B->data[j].value != 0 )
    		   {
                 C->nums++;
    			 C->data[C->nums].col = A->data[i].col;
    			 C->data[C->nums].row = A->data[i].row;
    			 C->data[C->nums].value = A->data[i].value+B->data[j].value;
    		   }
    		   i++;
    		   j++;//标记后移
    	   }
    	   else if( A->data[i].row*A->cols+A->data[i].col < B->data[j].row*B->cols+B->data[j].col )
    	   {
                 C->nums++;
    			 C->data[C->nums].col = A->data[i].col;
    			 C->data[C->nums].row = A->data[i].row;
    			 C->data[C->nums].value = A->data[i].value;
                 i++;
    	   }
    	   else
    	   {
                 C->nums++;
    			 C->data[C->nums].col = B->data[j].col;
    			 C->data[C->nums].row = B->data[j].row;
    			 C->data[C->nums].value = B->data[j].value;
    			 j++;
    	   }//if-else
    
       }//while,
    
       if( i == A->nums )
       {
    	   while( j < B->nums )
    	   {
                 C->nums++;
    			 C->data[C->nums].col = B->data[j].col;
    			 C->data[C->nums].row = B->data[j].row;
    			 C->data[C->nums].value = B->data[j].value;
    			 j++;
    	   }
       }
       else 
       {
    	   while( i < A->nums )
    	   {
                 C->nums++;
    			 C->data[C->nums].col = A->data[i].col;
    			 C->data[C->nums].row = A->data[i].row;
    			 C->data[C->nums].value = A->data[i].value;
                 i++;
    	   }
       }//if-else
    
       C->nums++;
    
       return C;
    }//AddMatrix
    

      下面是可直接编译运行的代码:

    /*************************************************************************
    	> File Name: Matrix.c
    	> Author: zh
    	> Mail: 574932286@qq.com 
    	> Created Time: 2014年10月16日 星期四 13时37分05秒
    	
    	一: 完成稀疏矩阵的建立i
        二: 15:33 稀疏矩阵的加法
             10,16 8:30 继续实现
    		 10.19 15:07 继续
        三: 10.20 00:44 稀疏矩阵得乘法	
     ************************************************************************/
    #include<stdlib.h>
    #include<stdio.h>
    #define MAXSIZE 100
    typedef int ElementType; 
    typedef struct 
    {
    	int row;
    	int col;
    	ElementType value;
    }Triple;
    
    typedef struct 
    {
    	Triple data[MAXSIZE];
    	int rows,cols,nums;//非零起
    }TSMatrix;
    
    typedef TSMatrix * PtrTSMatrix;
    
    PtrTSMatrix CreatMatrix( void );
    void PrintMatrix( PtrTSMatrix Matrix );
    PtrTSMatrix AddMatrix( PtrTSMatrix A, PtrTSMatrix B );
    PtrTSMatrix MinusMatrix( PtrTSMatrix A, PtrTSMatrix B );
    PtrTSMatrix MultiMatrix( PtrTSMatrix A, PtrTSMatrix B );
    /* Make a Matrix,use the triple array */
    PtrTSMatrix CreatMatrix( void )
    {
    
        int count = 0;
         PtrTSMatrix Matrix;
        Matrix  = ( PtrTSMatrix )malloc( sizeof( TSMatrix ) );
    	 if( Matrix == NULL )
         {
    		 printf("Not Space
     ");
    		 exit( 0 );
         }
    
         printf("输入行与列
    ");
    	 scanf("%d%d",&Matrix->rows,&Matrix->cols);
    
    	 printf("输入矩阵的元素的行,列,值( -1 结束 ,行优先)
    ");
         scanf("%d%d%d",&Matrix->data[count].row,&Matrix->data[count].col,&Matrix->data[count].value);
    	 while( Matrix->data[count].row != -1 )
    	 {
             count++;
             scanf("%d%d%d",&Matrix->data[count].row,&Matrix->data[count].col,&Matrix->data[count].value);
    		 if( Matrix->data[count].row < Matrix->data[count-1].row && Matrix->data[count].row!=-1 )
            {
    			printf("未按行输出:
    ");
    			getchar();
    			exit(0);
    		}//if
    	 }//while
        Matrix->nums = count;
    
    	 return Matrix;
    
    }/* CreatMatrix */
    
    /* print the matrix Matrix by using matrix */
    void PrintMatrix( PtrTSMatrix Matrix )
    {
          int i,j;
    	  int count = 0;
          
    	  for( i=0; i<Matrix->rows; i++ )
    	  {
    		  for( j=0; j<Matrix->cols; j++ )
    		  {
    			  if( count<Matrix->nums && i==Matrix->data[count].row-1 && j==Matrix->data[count].col-1 )
    			  {
      				  printf("%2d",Matrix->data[count].value);
    				  count++;
    			  }
    			  else
    			  {
    				  printf("%2d",0);
    			  }//if-else
    		  }//for
    		  printf("
    ");
    	  }//for
    }/* PrintMatrix */
    
    
    /* Plus A and B ,return C */
    PtrTSMatrix AddMatrix( PtrTSMatrix A, PtrTSMatrix B )
    {
    	int i=0,j=0;//标记追逐 A  B 
    	PtrTSMatrix C;//存放和
    
       if( A->rows!=B->rows || A->cols!=B->cols )
       {
    	   return NULL;
       }
       
       C = ( PtrTSMatrix )malloc(sizeof( TSMatrix ));
       C->rows = A->rows;
       C->cols = A->cols;
       C->nums = -1; //初始化
       
       while( i<A->nums && j<B->nums )
       {
    	   if( A->data[i].row*A->cols+A->data[i].col == B->data[j].row*B->cols+B->data[j].col )
    	   {
    		   if( A->data[i].value+B->data[j].value != 0 )
    		   {
                 C->nums++;
    			 C->data[C->nums].col = A->data[i].col;
    			 C->data[C->nums].row = A->data[i].row;
    			 C->data[C->nums].value = A->data[i].value+B->data[j].value;
    		   }
    		   i++;
    		   j++;//标记后移
    	   }
    	   else if( A->data[i].row*A->cols+A->data[i].col < B->data[j].row*B->cols+B->data[j].col )
    	   {
                 C->nums++;
    			 C->data[C->nums].col = A->data[i].col;
    			 C->data[C->nums].row = A->data[i].row;
    			 C->data[C->nums].value = A->data[i].value;
                 i++;
    	   }
    	   else
    	   {
                 C->nums++;
    			 C->data[C->nums].col = B->data[j].col;
    			 C->data[C->nums].row = B->data[j].row;
    			 C->data[C->nums].value = B->data[j].value;
    			 j++;
    	   }//if-else
    
       }//while,
    
       if( i == A->nums )
       {
    	   while( j < B->nums )
    	   {
                 C->nums++;
    			 C->data[C->nums].col = B->data[j].col;
    			 C->data[C->nums].row = B->data[j].row;
    			 C->data[C->nums].value = B->data[j].value;
    			 j++;
    	   }
       }
       else 
       {
    	   while( i < A->nums )
    	   {
                 C->nums++;
    			 C->data[C->nums].col = A->data[i].col;
    			 C->data[C->nums].row = A->data[i].row;
    			 C->data[C->nums].value = A->data[i].value;
                 i++;
    	   }
       }//if-else
    
       C->nums++;
    
       return C;
    }//AddMatrix
    /* A mius B get C */
    PtrTSMatrix MinusMatrix( PtrTSMatrix A, PtrTSMatrix B )
    {
    	int i=0,j=0;//标记追逐 A  B 
    	PtrTSMatrix C;//存放和
    
       if( A->rows!=B->rows || A->cols!=B->cols )
       {
    	   return NULL;
       }
       
       C = ( PtrTSMatrix )malloc(sizeof( TSMatrix ));
       C->rows = A->rows;
       C->cols = A->cols;
       C->nums = -1; //初始化
       
       while( i<A->nums && j<B->nums )
       {
    	   if( A->data[i].row*A->cols+A->data[i].col == B->data[j].row*B->cols+B->data[j].col )
    	   {
    		   if( A->data[i].value-B->data[j].value != 0 )
    		   {
                 C->nums++;
    			 C->data[C->nums].col = A->data[i].col;
    			 C->data[C->nums].row = A->data[i].row;
    			 C->data[C->nums].value = A->data[i].value-B->data[j].value;
    		   }
    		   i++;
    		   j++;//标记后移
    	   }
    	   else if( A->data[i].row*A->cols+A->data[i].col < B->data[j].row*B->cols+B->data[j].col )
    	   {
                 C->nums++;
    			 C->data[C->nums].col = A->data[i].col;
    			 C->data[C->nums].row = A->data[i].row;
    			 C->data[C->nums].value = A->data[i].value;
                 i++;
    	   }
    	   else
    	   {
                 C->nums++;
    			 C->data[C->nums].col = B->data[j].col;
    			 C->data[C->nums].row = B->data[j].row;
    			 C->data[C->nums].value = B->data[j].value;
    			 j++;
    	   }//if-else
    
       }//while,
    
       if( i == A->nums )
       {
    	   while( j < B->nums )
    	   {
                 C->nums++;
    			 C->data[C->nums].col = B->data[j].col;
    			 C->data[C->nums].row = B->data[j].row;
    			 C->data[C->nums].value = B->data[j].value;
    			 j++;
    	   }
       }
       else 
       {
    	   while( i < A->nums )
    	   {
                 C->nums++;
    			 C->data[C->nums].col = A->data[i].col;
    			 C->data[C->nums].row = A->data[i].row;
    			 C->data[C->nums].value = A->data[i].value;
                 i++;
    	   }
       }//if-else
    
       C->nums++;
    
       return C;
    }/* MiinusMatrix */
    
    
    /* get the answer of A multiply B */
    PtrTSMatrix MultiMatrix( PtrTSMatrix A, PtrTSMatrix B )
    {
    	PtrTSMatrix C;
        int num[MAXSIZE]={0};//第K行得非零元素得个数
    	int cpot[MAXSIZE]={0};//k行得第一个非零元素在三元组得位置
    	int i,j;
    	int count = 0;
        int temp[MAXSIZE]={0};
    
    	if( A->cols != B->cols )
    	{
           return NULL;
    	}//if ,输入检验
    
    	C = (PtrTSMatrix)malloc( sizeof(TSMatrix) );
    	C->rows = A->rows;
    	C->cols = B->cols;
    
    	for( i=0; i<B->nums; i++)
    	{
            num[B->data[i].row-1]++;//m
    		if( i!=0 && B->data[i-1].row!=B->data[i].row )
    		{
                cpot[B->data[i-1].row-1] = i;
    		}
    	}
    
        for( i=0; i<A->nums; i++ )
    	{
    		if( i!=0 && A->data[i].row != A->data[i-1].row )
    		{
                   
    			   for( j=0; j < B->cols; j++ )
    			   {
    				   if( temp[j] != 0 )
    				   {
                          C->data[count].row = A->data[i-1].row;
    					  C->data[count].col = j+1;
    					  C->data[count].value = temp[j];
                         count++;
    				   }
    			   }//for,赋值
    			   
    			   for( j=0; j<B->cols; j++ )
    			   {
    				   temp[j] = 0;
    			   }//for,初始化
    
    		}//if
    
    		for( j=0; j<num[A->data[i].col]; j++)
    		{
    			temp[ B->data[ cpot[A->data[i].col]+j ].col ]  = + A->data[i].value*B->data[ cpot[A->data[i].col]+j ];//高度注意,自己写一下
    		}//for
    
    	}//for
    	
    	return C;
    
    
    }//MultiMatrix
    int main(void)
    {
       PtrTSMatrix A,B,C,D,E;
       A = CreatMatrix();
       B = CreatMatrix();
      
       C = AddMatrix( A, B );
       D = MinusMatrix( A , B );
       E = MultiMatrix( A, B );
       printf("
    ");
       PrintMatrix( C );
       printf("
    ");
       PrintMatrix( D );
       printf("
    ");
       PrintMatrix( E );
       return 0;
    }
    

      

     

                   

  • 相关阅读:
    利用Express模拟web安全之---xss的攻与防
    JavaScript之引用类型
    JavaScript之变量、作用域和内存问题
    linux学习之缓存机制
    linux学习之vimrc配置推荐
    linux系统之free命令详解
    JavaScript之函数
    JavaScript之语句
    JavaScript之字符串、对象及操作符
    Navicat for MySQL 之数据库迁移
  • 原文地址:https://www.cnblogs.com/dilidingzhi/p/4028665.html
Copyright © 2020-2023  润新知