14. 稀疏矩阵的乘法运算

问题

描述

  • 数据压缩是提高传输、存储效率一种技术。教材第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;
}

小结

  1. 变量使用之前千万要初始化
  2. 动态数组不能在声明的同时进行初始化,初始化需要在声明完成之后
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值