问题
描述
- 数据压缩是提高传输、存储效率一种技术。教材第5章介绍了两种简单的压缩存储方法。
本实验要求实现两个稀疏矩阵相乘积的算法。其中稀疏矩阵非零元素数量小于100.
输入
- 第1个稀疏矩阵的行数
列数
非零元个数(三个数都大于0)
三元组
第2个稀疏矩阵的行数
列数
非零元个数(三个数都大于0)
三元组
以行为主序输入稀疏矩阵三元组表
输出
- 乘积矩阵的行数
列数
非零元个数(三个数都大于0)
三元组
测试用例
-
测试输入
-
3↵
4↵
4↵
1 1 3↵
1 4 5↵
2 2 -1↵
3 1 2↵
4↵
2↵
4↵
1 2 2↵
2 1 1↵
3 1 -2↵
3 2 4↵ -
期待输出
-
3↵
2↵
3↵
1,2,6↵
2,1,-1↵
3,2,4↵
解题
基本思想
-
每次计算Q中的一行元素,当前行号为arrow。
-
设临时变量ctemp[ ]保存该行元素,将其清零。
-
计算每行元素:
-
M中第arrow行的每一个元素(arrow, j)分别与N中第j行的元素(j, ccol)相乘,其结果累加到ctemp[ccol]中。
-
计算完后将该行元素压缩存储到Q的三元组中
代码
#include<iostream>
#include<cstring>
#include<cstdlib>
using namespace std;
// 三元组节点
typedef struct node{
int i; // 行
int j; //列
int data; //数据值
}NODE;
NODE *multmatrix(NODE *mam, NODE m[], NODE *man, NODE n[],NODE *q,NODE *qtu){
int a,b,d;
// 新矩阵的列数由n的列数决定
int temp[man->j];
int index=0;
qtu->data=0;
// 遍历属于m每一行的元素
for(a=1;a<=mam->i;a++){
// 初始化
for(b=0;b<man->j;b++){
temp[b]=0;
}
// 遍历三元组m中每一个元素
for(b=0;b<mam->data;b++){
// 找到属于m中正在操作的这一行的元素
if(m[b].i==a){
// 遍历n中每一个元素
for(d=0;d<man->data;d++){
// 找到n的行和m的列相同的元素
if(n[d].i==m[b].j){
//累加
temp[(n[d].j)-1]+=m[b].data * n[d].data;
}
}
}
}
//把临时数组里的值存进去
for(b=0;b<man->j;b++){
if(temp[b]!=0){
q[index].i=a;
q[index].j=b+1;
q[index].data = temp[b];
index ++;
}
}
}
qtu->data=index;
return qtu;
}
int main(){
int index;
// 矩阵的行、列、非零元个数刚好是三个数据,可以利用
NODE matrixm,matrixn;
//freopen("file in.txt","r",stdin);
// 输入m的行、列、非零元个数
cin>>matrixm.i>>matrixm.j>>matrixm.data;
NODE mtriplet[matrixm.data];
for(index=0;index<matrixm.data;index++){
cin>>mtriplet[index].i>>mtriplet[index].j>>mtriplet[index].data;
}
cin>>matrixn.i>>matrixn.j>>matrixn.data;
NODE ntriplet[matrixn.data];
for(index=0;index<matrixn.data;index++){
cin>>ntriplet[index].i>>ntriplet[index].j>>ntriplet[index].data;
}
// 矩阵可以相乘的条件
if(matrixm.j!=matrixn.i){
return 0;
}
NODE result[matrixm.i * matrixn.j];
NODE matrixresult;
matrixresult.i = matrixm.i;
matrixresult.j = matrixn.j;
// 如果是个空矩阵,返回
if(matrixresult.i * matrixresult.j ==0){
return 0;
}
multmatrix(&matrixm,mtriplet,&matrixn,ntriplet,result,&matrixresult);
cout<<matrixresult.i<<endl;
cout<<matrixresult.j<<endl;
cout<<matrixresult.data<<endl;
for(index=0;index<matrixresult.data;index++){
cout<<result[index].i<<",";
cout<<result[index].j<<",";
cout<<result[index].data<<endl;
}
return 0;
}
小结
- 变量使用之前千万要初始化
- 动态数组不能在声明的同时进行初始化,初始化需要在声明完成之后