Description
计算两个稀疏矩阵的乘法
Input
首先输入第一个矩阵的行数和列数,再输入该矩阵的三元组形式,以0 0 0结束
然后输入第二个矩阵的行数和列数,再输入该矩阵的三元组形式,以0 0 0结束
Output
输出相加后的矩阵三元组。
-
Sample Input
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
-
Sample Output
1 3 -2 2 1 32 2 2 -24 2 3 -10 3 3 8
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define MAXSIZE 1024
typedef struct {
int i,j;
int e;
}Triple;
typedef struct {
Triple data[MAXSIZE];
int mu,nu,tu;
}TSMatrix;
TSMatrix *Create(TSMatrix *A)
{
int m,n,i;
scanf("%d %d",&m,&n);
A->mu=m;
A->nu=n;
A->tu=0;
for(i=0;;i++)
{
scanf("%d %d %d",&A->data[i].i,&A->data[i].j,&A->data[i].e);
if(A->data[i].i==0&&A->data[i].j==0&&A->data[i].e==0)
break;
A->tu++;
}
return A;
}
void output(TSMatrix *M)
{
int i;
for(i=0;i<M->tu;i++)
{
printf("%d %d %d\n",M->data[i].i,M->data[i].j,M->data[i].e);
}
}
TSMatrix * MultiTSM(TSMatrix *A,TSMatrix *B)
{
TSMatrix *C;
int p,j,q,i,r,k,t;
int temp[B->nu+1];
int cnt[B->mu+1],num[B->mu+1];
C = (TSMatrix*)malloc(sizeof(TSMatrix));
if(A->nu!=B->mu) return NULL;
C->mu = A->mu;
C->nu = B->nu;
if(A->tu*B->tu==0)
{
C->tu = 0;
return C;
}
for(i = 1;i<=B->mu;i++)
cnt[i] = 0;
for(i = 0;i<B->tu;i++)
cnt[B->data[i].i]++;
num[1] = 0;
for(i = 2;i<=B->mu;i++)
num[i] = num[i-1]+cnt[i-1];
r = 0;//记录当前C矩阵中非0元素的个数
p = 0;//指示当前A矩阵中非零元素的位置
//进行矩阵的乘积运算
for(i = 1;i<=A->mu;i++)
{
for(j = 1;j<=B->nu;j++)
temp[j] = 0;
while(i==A->data[p].i)
{
k = A->data[p].j;
if(k<B->mu) t = num[k+1];
else t = B->tu;
for(q = num[k];q<t;q++)
{
j = B->data[q].j;
temp[j] += A->data[p].e*B->data[q].e;
}
p++;
}
for(j = 1;j<=B->nu;j++)
{
if(temp[j]!=0){
C->data[r] = {i,j,temp[j]};
r++;
}
}
}
C->tu = r;
return C;
}
int main()
{
TSMatrix *A;
TSMatrix *B;
TSMatrix *C;
A = (TSMatrix*)malloc(sizeof(TSMatrix));
B = (TSMatrix*)malloc(sizeof(TSMatrix));
A=Create(A);
B=Create(B);
C=MultiTSM(A,B);
output(C);
return 0;
}
快速乘法如下:
#include <iostream>
#include <stdio.h>
using namespace std;
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define INFEASIBLE -1
#define MAXSIZE 12500
#define MAXRC 100
#define ElemType int
typedef struct
{
int i,j;//行,列
ElemType e;//元素值
}Triple;
typedef struct
{
Triple data[MAXSIZE+1];
int rpos[MAXRC+1];//每行第一个非零元素在data数组中的位置
int mu,nu,tu;//行数,列数,元素个数
}RLSMatrix;
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 Findrpos(RLSMatrix &M)
{
int row;
int num[100];
for (row = 1; row <= M.mu; row++)
num[row] = 0; //num数组的初始化
for (int t = 1; t <= M.tu; t++)
++num[M.data[t].i]; //求M中每一行含有的非零元个数
M.rpos[1] = 1;
for (row = 2; row <= M.mu; row++)
M.rpos[row] = M.rpos[row - 1] + num[row - 1];
}
void PrintMartix(RLSMatrix &M)
{
int k;
for(k=1; k<=M.tu; k++)
cout<<M.data[k].i << " "<<M.data[k].j << " "<< M.data[k].e<<endl;
}
int main(int argc, char* argv[])
{
RLSMatrix M,N,T;
int m,n;
scanf("%d %d",&m,&n);
M.mu = m;
M.nu = n;
for(int i = 1;;i++)
{
scanf("%d %d %d",&M.data[i].i,&M.data[i].j,&M.data[i].e);
if(M.data[i].i==0&&M.data[i].j==0&&M.data[i].e==0)break;
M.tu++;
}
int x,y;
scanf("%d %d",&x,&y);
N.mu = x;
N.nu = y;
for(int i = 1;;i++)
{
scanf("%d %d %d",&N.data[i].i,&N.data[i].j,&N.data[i].e);
if(N.data[i].i==0&&N.data[i].j==0&&N.data[i].e==0)break;
N.tu++;
}
Findrpos(M);
Findrpos(N);
MultSMatrix(M,N,T);
PrintMartix(T);
return 0;
}