一般矩阵与稀疏矩阵三元组的乘法

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

  矩阵乘法算法原理:
  按行遍历A (A,B都是行增的)
  按列遍历B
  在遍历k,A的列和B的行匹配,C[i][j]+=A[i][k]*B[k][j] C的行是A的行,C的列是B的列

  稀疏矩阵三元组乘法原理:
  确定A,B中每一种行的个数,及其第一个的位置
  遍历A的每一种相同的行的每一个,找到其对应的列,再遍历与之匹配的B的行,B的行又匹配其对应存在的所有列
  此时A的行列对应的值乘上B的行列对应的值,C的该行列值累加即为答案
  举个例子:
  A的3行1列的值要乘上B的1行所有存在的列的值

先用的是数组形式

#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 row,col;
    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 i,j;
   M->len=0;
   while(!0)
   {
       scanf("%d%d%d",&x1,&x2,&x3);
       if(x1==0&&x2==0&&x3==0)
       break;
       M->data[M->len].row=x1;
       M->data[M->len].col=x2;
       M->data[M->len].elem=x3;
       M->len++;
   }
     if(M->len)
   {
     for(i=0;i<=M->m;i++)       //列数是从1开始的
     num[i]=0;
     for(j=0;j<M->len;j++)      //data是从0开始记的
     {
      num[M->data[j].row]++;    //与转置不同,这里找的是每一种行值有几个数。
     }                          //rpos是每一种行值的第一个非0元素在三元组中的位置
     M->rpos[0]=0;
     for(i=1;i<=M->m;i++)
     {
       M->rpos[i]=M->rpos[i-1]+num[i-1];
     }
      M->rpos[i]=M->len;    //这里的i是比总行数大1的,标志着A的最后一行的位置
   }
     return;
}
void multimatrix(TripleMatrix *A,TripleMatrix *B,TripleMatrix *C)
{
    int arow,brow,ccol;
    int i,j;
    int ctemp[MAXN];
    for(arow=1;arow<=A->m;arow++)
    {
        C->rpos[arow]=C->len;
        for(i=A->rpos[arow];i<A->rpos[arow+1];i++)   //i是该行列在A中对应的位置
        {
            memset(ctemp,0,sizeof(ctemp));
            brow=A->data[i].col;
            for(j=B->rpos[brow];j<B->rpos[brow+1];j++)  //j是该行列在B中对应的位置
          {
              ccol=B->data[j].col;
              ctemp[ccol]+=A->data[i].elem*B->data[j].elem;
          }
          for(ccol=0;ccol<=C->n;ccol++)
          {
                    if (ctemp[ccol]!=0)
                  {
                     C->data[C->len].row=arow;
                     C->data[C->len].col=ccol;
                     C->data[C->len].elem=ctemp[ccol];
                     C->len++;
                  }
          }
        }
    }
    return;
}
void print(TripleMatrix *C)
{
  int i;
  for(i=0;i<C->len;i++)
  printf("%d %d %d\n",C->data[i].row,C->data[i].col,C->data[i].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;
}
/*
测试用例:
3 3
1 1 1
2 2 2
2 3 4
3 1 -4
0 0 0
3 3
1 3 -2
2 3 -5
3 1 8
3 2 -6
0 0 0
*/

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

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值