行逻辑链接的矩阵乘法

来源:互联网 发布:妇幼保健网络信息系统 编辑:程序博客网 时间:2024/06/08 04:49

题目描述

对于一个稀疏矩阵,当需要频繁的随机存取任意一行的非零元时,则需要知道每一行的第一个非零元在三元组表中的位置。为此,可以将算法5.2中用来指示“行”信息的辅助数组cpot固定在稀疏矩阵的存储结构中。这种“带行链接信息”的三元组表即为行逻辑链接的顺序表。其类型描述如下:
针对存储于行逻辑链接顺序表的稀疏矩阵,其矩阵相乘的算法与经典算法有所不同。因此,对于两个稀疏矩阵相乘(Q=M×N)的过程可以大致描述如下:
请使用行逻辑链接的顺序表实现两个稀疏矩阵的乘法。

输入

输入的第一行是两个整数r1和c1(r1<200, c1<200, r1*c1 <= 12500),分别表示一个包含很多0的稀疏矩阵的行数和列数。接下来有r1行,每行有c1个整数,用空格隔开,表示第一个稀疏矩阵的各个元素。 之后的一行有两个整数r2和c2(c1=r2<200, c2<200, r2*c2 <= 12500),分别表示一个包含很多0的稀疏矩阵的行数和列数。接下来有r2行,每行有c2个整数,用空格隔开,表示第二个稀疏矩阵的各个元素。

输出

输出两个矩阵的乘积。输出共有r1行,每行有c2个整数,每个整数后输出一个空格。请注意行尾输出换行。

样例输入

4 50 0 0 69 780 0 5 0 00 0 0 0 00 91 2 0 825 60 18 0 0 0 00 0 67 0 0 00 0 0 0 0 410 0 47 62 0 00 0 0 0 0 35

样例输出

0 0 3243 4278 0 2730 0 0 0 0 0 205 0 0 0 0 0 0 0 0 6097 0 0 2952 

提示

*** 提示已隐藏,点击此处可显示 ***
收起提示[-]

提示:
对于稀疏矩阵M和N,其相乘的基本操作是:对于M中每个元素M.data[p](p=1,2,...,M.tu),找到N中所有满足条件M.data[p].j=N.data[q].i的元素N.data[q],从而求得M.data[p]与M.data[q]的乘积。需要注意的是,这个乘积只是Q[i][j]中的一部分,需要将其累加从而得到最终的结果。
另外需要注意的是,两个稀疏矩阵相乘的乘积并不一定是稀疏矩阵。
总结:

#include<stdio.h>#define   TRUE                    1#define   FALSE                    0#define   OK                    1#define   ERROR                    0#define   OVERFLOW                -2#define   INFEASIBLE            -1#define MAXSIZE 12500#define MAXRC 200#define ElemType inttypedef struct{    int i,j;    ElemType  e;}Triple;typedef struct{    Triple data[MAXSIZE+1];    int rpos[MAXRC+1];    int mu,nu,tu;}RLSMatrix; RLSMatrix CreatSMatrix(){    RLSMatrix P;    int m,n,p,q,k,temp;    k=1;    scanf("%d%d",&m,&n);    P.tu=0;    P.mu=m;    P.nu=n;    //scanf("%d%d",&P.mu,&P.tu);    for( p=1;p<=m;p++)    {        P.rpos[p]=P.tu+1;        for( q=1;q<=n;q++)        {            scanf("%d",&temp);            if(temp)            {                P.data[k].i=p;                P.data[k].j=q;                P.data[k].e=temp;                k++;                P.tu++;            }         }    }    return P;}int MultSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix *Q){    if(M.nu != N.mu)//矩阵M的列数与矩阵N的行数不等,则不能做矩阵乘运算        return ERROR;    Q->mu = M.mu;    Q->nu = N.nu;    Q->tu = 0;    if(M.tu * N.tu == 0)//其中任意矩阵的元素个数为零,则不能做乘运算        return ERROR;    else    {        int arow;        int ccol;        for(arow=1; arow<=M.mu; arow++)//处理矩阵M的每一行        {            int ctemp[MAXRC+1] ={};            Q->rpos[arow] = Q->tu + 1;            int tp;            if(arow < M.mu)                tp = M.rpos[arow+1];//获取矩阵M的下一行第一个非零元素在data数组中位置            else                tp = M.tu+1;//若当前行是最后一行,则取最后一个元素+1            int p;            int brow;            for(p=M.rpos[arow]; p<tp; p++)//对当前矩阵M中的每一个非零元素,在矩阵N中找到对应可乘元素            {                brow = M.data[p].j;                int t;                if(brow < N.mu)                    t = N.rpos[brow+1];                else                    t = N.tu+1;                int q;                int ccol;                for(q=N.rpos[brow]; q<t; q++)                {                    ccol = N.data[q].j;                    ctemp[ccol] += M.data[p].e * N.data[q].e;                }            }            for(ccol=1; ccol<=Q->nu; ccol++)            {                if(ctemp[ccol])                {                    if(++Q->tu > MAXSIZE)                        return ERROR;                    Q->data[Q->tu].e = ctemp[ccol];                    Q->data[Q->tu].i = arow;                    Q->data[Q->tu].j = ccol;                }            }        }     return OK;    }}void print(RLSMatrix P){    int p,q,k=1;    for(p=1;p<=P.mu;p++)    {        for(q=1;q<=P.nu;q++)        {           if(P.data[k].i==p&&P.data[k].j==q)           {                printf("%d ",P.data[k].e);                k++;           }           else                printf("0 ");        }        printf("\n");    }}int main(){    RLSMatrix M,T,Q;    M=CreatSMatrix();    T=CreatSMatrix();    MultSMatrix(M,T,&Q);    print(Q);    return 0;}