稀疏矩阵的乘法(三元组)

稀疏矩阵的乘法(三元组)



先用的是数组形式

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int A[1000][1000],B[1000][1000],C[1000][1000];
int main()
{
    memset(A,0,sizeof(A));
    memset(B,0,sizeof(B));
    memset(B,0,sizeof(B));
    int i,j,k;
    int t1,t2,p1,p2;
    int a,b,temp;
    scanf("%d%d",&t1,&t2);
    while(!0)
    {
        scanf("%d%d%d",&a,&b,&temp);
        if(a==0&&b==0&&temp==0)
        break;
        A[a][b]=temp;
    }
    scanf("%d%d",&p1,&p2);
      while(!0)
    {
        scanf("%d%d%d",&a,&b,&temp);
        if(a==0&&b==0&&temp==0)
        break;
        B[a][b]=temp;
    }
    for (i=1;i<=t1;i++)
    for (j=1;j<=p2;j++)
    {


      for(k=1;k<=p1;k++)
      C[i][j]+=A[i][k]*B[k][j];
    }
    for(i=1;i<=t1;i++)
    for(j=1;j<=p2;j++)
    {
        if(C[i][j]!=0)
        printf("%d %d %d\n",i,j,C[i][j]);
    }
    return 0;

}



三元组储存形式

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXN 200
typedef struct
{
    int i,j;
    int elem;
}triple;
typedef struct
{
    triple data[MAXN];
    int rpos[MAXN];
    int m,n,len;
}triplematrix;
void intimatrix(triplematrix *M)  //取地址才能赋值啊
{
   int num[MAXN];
   scanf("%d%d",&(M->m),&(M->n));
   int x1,x2,x3;
   int ii,jj;
   M->len=0;
   while(!0)
   {
       scanf("%d%d%d",&x1,&x2,&x3);
       if(x1==0&&x2==0&&x3==0)
       break;
       M->data[M->len].i=x1;
       M->data[M->len].j=x2;
       M->data[M->len].elem=x3;
       M->len++;
   }
     if(M->len)
   {                              //num[i]也不是下标类,num才是0 0 1进入的原因。
     for(ii=0;ii<=M->m;ii++)     // 因为我没有限制超过矩阵的大小会产生错误,所以我没次多建了一行一列的矩阵
     num[ii]=0;
     for(jj=0;jj<M->len;jj++)  //data是从0开始记的
     {
      num[M->data[jj].i]++; //与转置不同,这里找的是每行有几个数。
     }                   //这步处理了三元组存矩阵,下标可能为0的情况
     M->rpos[0]=0;       //rpos就是统计以1或2等行数开头的相对位置的
                       //
     for(ii=1;ii<=M->m;ii++)//ii<=M->len
     {
       M->rpos[ii]=M->rpos[ii-1]+num[ii-1];
     }
       M->rpos[ii]=M->len;//因为下面要考虑边界,使ii=A->rpos[arow]最后一个<成立,但仅仅一次成立,M->rpos[3]要保留,M->rpos[4]不保留,极其重要
   }
     return;
}
void multimatrix(triplematrix *A,triplematrix *B,triplematrix *C)
{
    int arow,brow,ccol;
    int ii,jj;
    int ctemp[MAXN];
    for(arow=0;arow<=A->m;arow++)
    {
        C->rpos[arow]=C->len;        //  这步可以省略                                  ->column ->B->row  ->B->column
        for(ii=A->rpos[arow];ii<A->rpos[arow+1];ii++) //列举A中所有同行。  关系图A->row->column ->B->row  ->B->column ->C[row,column]
        {
            memset(ctemp,0,sizeof(ctemp));                                //                                       ->column ->B->row  ->B->column
    brow=A->data[ii].j;       //A的列对应B的行。
             for(jj=B->rpos[brow];jj<B->rpos[brow+1];jj++)  //列举B的所有同行
          {
 ccol=B->data[jj].j;         //rpos记录能获取相应位置的data ,data<n,arow,column<=n;
 ctemp[ccol]+=A->data[ii].elem*B->data[jj].elem;
          }
          for(ccol=0;ccol<=C->n;ccol++)
            {
          if (ctemp[ccol]!=0)              //
               {
        C->data[C->len].i=arow;
        C->data[C->len].j=ccol;
        C->data[C->len].elem=ctemp[ccol];
        C->len++;
      }
   }
        }
    }
    return;
}
void print(triplematrix *C)
{
  int ii;
  for(ii=0;ii<C->len;ii++)
  printf("%d %d %d\n",C->data[ii].i,C->data[ii].j,C->data[ii].elem);
  return;
}
int main()
{
   triplematrix A,B,C;
   intimatrix(&A);           //按我的惯用手法
   intimatrix(&B);           //矩阵的data下标都是从0开始
   C.m=A.m;                 //
   C.n=B.n;
   C.len=0;
   if (A.m==B.n)
   multimatrix(&A,&B,&C);
   print(&C);
   return 0;

}

外加一步排序,不用sort,我都不知怎么排

猜你喜欢

转载自blog.csdn.net/xigongdali/article/details/80023727
今日推荐