⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 haha.c

📁 矩阵运算包含加减乘三元组顺序表存储的c语言
💻 C
字号:
  #include <stdio.h>

  #include <conio.h>

  #include <stdlib.h>

 

  #define MAXR 20  /*最大行数*/

  #define MAXC 20  /*最大列数*/

  #define MAXSIZE MAXR*MAXC  /*最多非零元个数*/

 

  typedef struct{

    int i;  /*行下标*/

    int j;  /*列下标*/

    int e;  /*非零元值*/

  }Triple;  /*三元组类型*/

 

  typedef struct {

    Triple data[MAXSIZE];  /*三元组表*/

    int *rpos;  /*指向各行第一个非零元的位置表*/

    int mu;  /*行数*/

    int nu;  /*列数*/

    int tu;  /*非零元个数*/

  }RLSMatrix;

 

  int CreatSM(RLSMatrix *M){

    /*创建稀疏矩阵M*/

    int i,t=0,prei=0,prej=0;

 

    do{

      printf("\n请输入矩阵的行数(1~%d):",MAXR);

      scanf("%d",&M->mu);

    }while(M->mu<1||M->mu>MAXR);

 

    do{

      printf("请输入矩阵的列数(1~%d):",MAXC);

      scanf("%d",&M->nu);

    }while(M->nu<1||M->nu>MAXC);

 

    printf("请按行序输入各三元组,输入0,0,0表示结束。\n");

 

    while(t<MAXSIZE){

      printf("%3d:  ",t+1);

      scanf("%d,%d,%d",&M->data[t].i,&M->data[t].j,&M->data[t].e);

      if (!M->data[t].i&&!M->data[t].j&&!M->data[t].e) break;

      if (M->data[t].i<1||M->data[t].i>M->mu){

       printf("行下标越界!请重新输入!\n");

        continue;

      }

      if (M->data[t].j<1||M->data[t].j>M->nu){

        printf("列下标越界!请重新输入!\n");

        continue;

      }

      if ((M->data[t].i<prei)||(M->data[t].i==prei&&M->data[t].j<prej)){

        printf("\n错误!未按行序输入三元组!\n按任一键返回主菜单...");

        getch();

        return 0;

      }

      prei=M->data[t].i;

      prej=M->data[t].j;

      t++;

    }/*while*/

 

    M->tu=t;

 

    if (M->rpos) free(M->rpos);

    M->rpos=(int *)malloc(M->mu*sizeof(int));

    if (!M->rpos) exit(-2);

 

    t=0;

    for(i=0;i<M->mu;++i){

      M->rpos[i]=t;

      while(M->data[t].i==i+1) t++;

    }

    return 1;

  }/*CreatSM*/

 

  void PrintSM(RLSMatrix *M){

    /*输出稀疏矩阵M*/

    int i,j,t;

    t=0;

    for(i=1;i<=M->mu;++i){

      for(j=1;j<=M->nu;++j){

       if ((M->data[t].i==i)&&(M->data[t].j==j)){

         printf("%5d",M->data[t].e);

         t++;

       }/*if*/

       else printf("%5d",0);

      }/*for_j*/

      printf("\n");

    }/*for_i*/

  }/*PrintSM*/

 

  int AddSM(RLSMatrix *M, RLSMatrix *N ,RLSMatrix *Q){

    /*稀疏矩阵相加,Q=M+N*/

    int row,d,pm,pn,qm,qn;

    if (M->mu!=N->mu||M->nu!=N->nu){

      printf("\n两矩阵行列数不等,不能相加!\n按任一键继续...");

      getch();

      return 0;

    }/*if*/

 

    Q->mu=M->mu;

    Q->nu=M->nu;

    Q->tu=0;

 

    if (Q->rpos) free(Q->rpos);

    Q->rpos=(int *)malloc(Q->mu*sizeof(int));

    if (!Q->rpos) exit(-2);

 

    for(row=0;row<Q->mu;++row){

      pm=M->rpos[row];

      pn=N->rpos[row];

      Q->rpos[row]=Q->tu;

      if (row==Q->mu-1){ qm=M->tu;  qn=N->tu; }

      else{ qm=M->rpos[row+1];  qn=N->rpos[row+1]; }

      /*令qm指向M中当前行最后一个三元组的下一位置*/

      /*令qn指向N中当前行最后一个三元组的下一位置*/

      while(pm<qm&&pn<qn){

       if (M->data[pm].j<N->data[pn].j){

          /*M中当前三元组列下标较小,即N中对应位置为零元素*/

         Q->data[Q->tu].i=M->data[pm].i;

         Q->data[Q->tu].j=M->data[pm].j;

         Q->data[Q->tu].e=M->data[pm].e;

          Q->tu++;

          pm++;

        }

       else if (M->data[pm].j>N->data[pn].j){/*N中当前三元组列下标较小*/

              Q->data[Q->tu].i=N->data[pn].i;

              Q->data[Q->tu].j=N->data[pn].j;

              Q->data[Q->tu].e=N->data[pn].e;

               Q->tu++;

               pn++;

             }

             else{/*M和N中当前三元组列下标相等*/

              d=M->data[pm].e+N->data[pn].e;

               if (d){

               Q->data[Q->tu].i=M->data[pm].i;

               Q->data[Q->tu].j=M->data[pm].j;

                 Q->data[Q->tu].e=d;

                 Q->tu++;

               }/*if_d*/

               pm++;

               pn++;

             }/*else*/

      }/*while*/

      while(pm<qm){

       Q->data[Q->tu].i=M->data[pm].i;

       Q->data[Q->tu].j=M->data[pm].j;

       Q->data[Q->tu].e=M->data[pm].e;

        Q->tu++;

        pm++;

      }/*while_pm<qm*/

      while(pn<qn){

       Q->data[Q->tu].i=N->data[pn].i;

       Q->data[Q->tu].j=N->data[pn].j;

       Q->data[Q->tu].e=N->data[pn].e;

        Q->tu++;

        pn++;

      }/*while_pn<qn*/

    }/*for*/

    return 1;

  }/*AddSM*/

 

  int MinusSM(RLSMatrix *M, RLSMatrix *N ,RLSMatrix *Q){

    /*稀疏矩阵相减,Q=M-N*/

    int row,d,pm,pn,qm,qn;

    if (M->mu!=N->mu||M->nu!=N->nu){

      printf("\n两矩阵行列数不等,不能相减!\n按任一键继续...");

      getch();

      return 0;

    }/*if*/

    Q->mu=M->mu;

    Q->nu=M->nu;

    Q->tu=0;

    if (Q->rpos) free(Q->rpos);

    Q->rpos=(int *)malloc(Q->mu*sizeof(int));

    if (!Q->rpos) exit(-2);

    pm=M->rpos[0]; /*令pm指向M中第一行第一个三元组*/

    pn=N->rpos[0]; /*令pn指向N中第一行第一个三元组*/

 

    for(row=0;row<Q->mu;++row){

      Q->rpos[row]=Q->tu;

      if (row==Q->mu-1){ qm=M->tu;  qn=N->tu; }

      else{ qm=M->rpos[row+1];  qn=N->rpos[row+1]; }

      /*令qm指向M中当前行最后一个三元组的下一位置*/

      /*令qn指向N中当前行最后一个三元组的下一位置*/

      while(pm<qm&&pn<qn){

        if (M->data[pm].j<N->data[pn].j){

          /*M中当前三元组列下标较小,即N中对应位置为零元素*/

          Q->data[Q->tu].i=M->data[pm].i;

          Q->data[Q->tu].j=M->data[pm].j;

          Q->data[Q->tu].e=M->data[pm].e;

          Q->tu++;

          pm++;

        }

        else if (M->data[pm].j>N->data[pn].j){/*N中当前三元组列下标较小*/

               Q->data[Q->tu].i=N->data[pn].i;

               Q->data[Q->tu].j=N->data[pn].j;

               Q->data[Q->tu].e=-N->data[pn].e;

               Q->tu++;

               pn++;

             }

             else{/*M和N中当前三元组列下标相等*/

               d=M->data[pm].e-N->data[pn].e;

               if (d){

                 Q->data[Q->tu].i=M->data[pm].i;

                 Q->data[Q->tu].j=M->data[pm].j;

                 Q->data[Q->tu].e=d;

                 Q->tu++;

               }/*if_d*/

               pm++;

               pn++;

             }/*else*/

      }/*while*/

      while(pm<qm){

        Q->data[Q->tu].i=M->data[pm].i;

        Q->data[Q->tu].j=M->data[pm].j;

        Q->data[Q->tu].e=M->data[pm].e;

        Q->tu++;

        pm++;

      }/*while_pm<qm*/

      while(pn<qn){

        Q->data[Q->tu].i=N->data[pn].i;

        Q->data[Q->tu].j=N->data[pn].j;

        Q->data[Q->tu].e=-N->data[pn].e;

        Q->tu++;

        pn++;

      }/*while_pn<qn*/

    }/*for*/

    return 1;

  }/*MinusSM*/

 

  int MultSM(RLSMatrix *M, RLSMatrix *N ,RLSMatrix *Q){

    /*稀疏矩阵相乘,Q=M*N */

    int i,j,p,q,k,tn,tm;

    int ctemp[MAXC];

    if (M->nu!=N->mu){

      printf("\n左阵列数与右阵行数不等,不能相乘!\n按任一键继续...");

      getch();

      return 0;

    }/*if*/

    Q->mu=M->mu;

    Q->nu=N->nu;

    Q->tu=0;

    if (M->tu&&N->tu){

      if (Q->rpos) free(Q->rpos);

      Q->rpos=(int *)malloc(Q->mu*sizeof(int));

      if (!Q->rpos) exit(-2);

      for(i=0;i<M->mu;++i){/*对M (亦即Q) 的每行*/

       for(j=0;j<Q->nu;++j)

         ctemp[j]=0;  /*ctemp中暂存Q当前行各元素值*/

       Q->rpos[i]=Q->tu;  /*Q当前行第一个非零元的存储位置*/

       if (i<M->mu-1) tm=M->rpos[i+1];

         else tm=M->tu;

       for(p=M->rpos[i];p<tm;++p){

          k=M->data[p].j-1;

         if (k<N->mu-1) tn=N->rpos[k+1];

         else tn=N->tu;

         for(q=N->rpos[k];q<tn;++q){

            j=N->data[q].j-1;

            ctemp[j]+=M->data[p].e*N->data[q].e;

          }/*for_q*/

        }/*for_p*/

        for(j=0;j<Q->nu;++j)/*压缩存储Q的当前行*/

          if (ctemp[j]){/*若当前元素为非零元*/

           if (Q->tu==MAXSIZE){

              printf("\nQ中非零元过多!\n按任一键继续...");

              getch();

              return 0;

           }/*if*/

            Q->data[Q->tu].i=i+1;

            Q->data[Q->tu].j=j+1;

           Q->data[Q->tu].e=ctemp[j];

           Q->tu++;

          }/*if_ctemp[j]*/

       }/*for_i*/

    }/*if_M.tu&&N.tu*/

    return 1;

  }/*MultSM*/

 

  main(){

    RLSMatrix M,N,Q;

    int end=0;

    char choice;

    M.rpos=N.rpos=Q.rpos=NULL;

    while(!end){

      clrscr();

      printf("  欢迎使用稀疏矩阵运算器\n");

      printf("**************************\n\n");

      printf("1-矩阵相加\n");

      printf("2-矩阵相减\n");

      printf("3-矩阵相乘\n");

      printf("0-退    出\n");

      printf("请输入您的选择(1,2,3,0):");

      do{

        scanf("%c",&choice);

      }while(choice-'0'<0||choice-'0'>3);

      switch(choice){

        case '1':

          clrscr();

          printf("请输入第一个矩阵\n");

          printf("==============\n");

         if (CreatSM(&M)){

           printf("\n请输入第二个矩阵\n");

           printf("==============\n");

           if (CreatSM(&N)){

             if (AddSM(&M,&N,&Q)){

                printf("\n两矩阵之和为:\n");

              PrintSM(&Q);

               printf("\n按任一键继续...");

                getch();

              }

            }

          }

          break;

        case '2':

          clrscr();

          printf("请输入第一个矩阵\n");

          printf("==============\n");

          if (CreatSM(&M)){

            printf("\n请输入第二个矩阵\n");

            printf("==============\n");

            if (CreatSM(&N)){

              if (MinusSM(&M,&N,&Q))
              {
              printf("\n两矩阵之差为:\n");

              PrintSM(&Q);

               printf("\n按任一键继续...");

                getch();

              }

            }

          }

          break;

        case '3':

          clrscr();

          printf("请输入第一个矩阵\n");

          printf("==============\n");

          if (CreatSM(&M)){

            printf("\n请输入第二个矩阵\n");

            printf("==============\n");

            if (CreatSM(&N)){

             if (MultSM(&M,&N,&Q)){

                printf("\n两矩阵之积为:\n");

              PrintSM(&Q);

               printf("\n按任一键继续...");

                getch();

              }

            }

          }

          break;

        case '0':

          end=1;

      }/*switch*/

    }/*while_end*/

  }/*main*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -