稀疏矩阵的乘法(三元组)
矩阵乘法算法原理:
按行遍历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,我都不知怎么排