实现稀疏矩阵相乘C/C++

实现稀疏矩阵相乘C/C++实现稀疏矩阵相乘 C C 1 问题描述 已知稀疏矩阵 A m1 n1 和 B m2 n2 求乘积 C m1 n2 A 300 nbsp 7 nbsp nbsp B 4 nbsp 1 nbsp C 1217 nbsp nbsp nbsp 000 1 nbsp nbsp nbsp nbsp 0 nbsp 0 nbsp nbsp nbsp nbsp 0 nbsp nbsp 2 nbsp nbsp nbsp 020 nbsp 0 nbsp nbsp nbsp nbsp 1 1 nbsp nbsp nbsp nbsp 0 nbsp nbsp nbsp 0 nbsp nbsp

实现稀疏矩阵相乘C/C++

1、问题描述:已知稀疏矩阵A(m1,n1)和B(m2,n2),求乘积C(m1,n2)。
A=|3 0 0  7|    B=|4  1|   C=|12 17|
     |0 0 0 -1|         |0  0|        |0    -2|
     |0 2 0  0|         |1 -1|        |0      0|
                             |0   2|
A、B、C的三元组表示法分别为:

A
  i j v
1 1 1 2
2 1 4 7
3 2 4 -1
4 3 2 2
B
  i j v
1 1 1 4
2 1 2 1
3 3 1 1
4 3 2 -1
5 4 2 2
C
  i j v
1 1 1 12
2 1 2 17
3 2 2 -2

2、解决思路:由矩阵乘法规则可知C(i,j) = A(i,1)*B(1,j)+A(i,2)*B(2,j)+….+A(i,n)*B(n,j),即C(i,j)为A的第i行与B的第j列非零元素乘积之和。设置累加器temp[B的列值]保存C矩阵每行的值,结束后将temp中的值赋给C矩阵。

3、定义数据结构:
3.1、稀疏矩阵中节点的定义:

//定义三元组表的节点 typedef struct{ int i,j; int v; }SPNode;

i,j为行列值,v为此位置的数值。

3.2、稀疏矩阵的定义:

//定义三元组表 typedef struct{ int mu,nu,tu; SPNode data[SMAX]; }SPMatrix;

mu为矩阵行数,nu为矩阵列数,tu为矩阵中非零元素的个数。

4、具体实现:
为了便于B.data寻找第k行第一个非零元素,在此引入num和rpot两个内容。num[k]表示矩阵B中第k行非零元素的个数;rpot[k]表示第k行的第一个非零元素在B.data中的位置。
rpot[1] = 0;
rpot[k] = rpot[k-1]+num[k-1];
矩阵B中的num与rpot的值
col 1 2 3 4
num[col] 2 0 2 0
rpot[col] 0 2 2 4

4.1、初始化。清理一些单元,准备按行顺序存放乘积矩阵。

4.2、求B的num与rpot。
4.3、做矩阵的乘法。
5、代码的具体实现:

/* *进行两个稀疏矩阵之间的乘法 */ #include 
   
     #include 
    
      #define SMAX 1024 //定义三元组表的节点 typedef struct{ int i,j; int v; }SPNode; //定义三元组表 typedef struct{ int mu,nu,tu; SPNode data[SMAX]; }SPMatrix; //进行两个稀疏矩阵之间的乘法,返回值为乘积矩阵 SPMatrix * MulSMatrix(SPMatrix *A,SPMatrix *B){ SPMatrix *C; int p,j,q,i,r,k,t; //用于结果的暂存 int temp[B->nu+1]; int num[B->mu+1],rpot[B->mu+1]; C = (SPMatrix*)malloc(sizeof(SPMatrix)); if(C==NULL){ printf("申请内存空间失败!\n"); return NULL; } //A的列值与B的行值不相等时 if(A->nu!=B->mu) return NULL; C->mu = A->mu; C->nu = B->nu; //当A或B中的非零元素为0时 if(A->tu*B->tu==0){ C->tu = 0; return C; } //计算B矩阵中每行非0元素的个数 for(i = 1;i<=B->mu;i++) num[i] = 0; for(i = 0;i 
     
       tu;i++) num[B->data[i].i]++; rpot[1] = 0; //计算B矩阵中每行首位非0元素的位置 for(i = 2;i<=B->mu;i++) rpot[i] = rpot[i-1]+num[i-1]; r = 0;//记录当前C矩阵中非0元素的个数 p = 0;//指示当前A矩阵中非零元素的位置 //进行矩阵的乘积运算 for(i = 1;i<=A->mu;i++){ //将Cij的累加器初始化 for(j = 1;j<=B->nu;j++) temp[j] = 0; //求Cij第i行的元素集合 while(i==A->data[p].i){ k = A->data[p].j;//获取A矩阵中第p个非零元素的列值 //确定B中的k行的非零元素在B.data中的下限位置 if(k 
      
        mu) t = rpot[k+1]; else t = B->tu; //将B中第k行的每一列非零元素与A中非零元素记录到累加器中 for(q = rpot[k];q 
       
         data[q].j; temp[j] += A->data[p].v*B->data[q].v; } p++; } //将第i行的结果赋值给C矩阵 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(){ SPMatrix *A,*B,*C; int i; A = (SPMatrix*)malloc(sizeof(SPMatrix)); B = (SPMatrix*)malloc(sizeof(SPMatrix)); printf("请输入A矩阵的行列值与非零元素"); scanf("%d %d %d",&A->mu,&A->nu,&A->tu); printf("请输入A矩阵的非零元素值:\n"); for(i = 0;i 
        
          tu;i++) scanf("%d %d %d",&A->data[i].i,&A->data[i].j,&A->data[i].v); printf("请输入B矩阵的行列值与非零元素"); scanf("%d %d %d",&B->mu,&B->nu,&B->tu); printf("请输入B矩阵阵的非零元素值:\n"); for(i = 0;i 
         
           tu;i++) scanf("%d %d %d",&B->data[i].i,&B->data[i].j,&B->data[i].v); C = MulSMatrix(A,B); printf("C->nu:%d,C->mu:%d,C->tu:%d\n",C->mu,C->nu,C->tu); for(i = 0;i 
          
            tu;i++) printf("i:%d,j:%d,v:%d\n",C->data[i].i,C->data[i].j,C->data[i].v); delete A,B,C; return 0; } 
           
          
         
        
       
      
     
   

5、算法的时间复杂度:

5.1、求num的时间复杂度为:O(2*B->nu)
5.2、求rpot的时间复杂度为:O(B->mu)
5.3、求temp的时间复杂度为:O(A->mu*B->nu)
5.4、求C中所有元素的时间复杂度为:O(A->tu*B->tu/B->mu)











版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/212747.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 下午7:21
下一篇 2026年3月18日 下午7:22


相关推荐

  • idea2021.7.16激活码(JetBrains全家桶)「建议收藏」

    (idea2021.7.16激活码)JetBrains旗下有多款编译器工具(如:IntelliJ、WebStorm、PyCharm等)在各编程领域几乎都占据了垄断地位。建立在开源IntelliJ平台之上,过去15年以来,JetBrains一直在不断发展和完善这个平台。这个平台可以针对您的开发工作流进行微调并且能够提供…

    2022年3月21日
    56
  • 用FastJson将JSON字符串转Json[通俗易懂]

    用FastJson将JSON字符串转Json[通俗易懂]一、导入jar<!–fastjson–><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.1.15</version></dependency>二、Fas

    2026年4月15日
    4
  • minipcie usb总线_ipadmini2换wifi模块

    minipcie usb总线_ipadmini2换wifi模块1、概述EC20R2.1MiniPCIe-C模块是PCIExpressMiniCard1.2标准接口LTE模块。本文章主要讲解了如何驱动EC20R2.1MiniPCIe-C模块的硬件电路设计,主要包含有:电源设计通讯接口SIM卡的防护1.1、EC20R2.1MiniPCIe-C模块引脚分配1.2、EC20R2.1MiniPCIe-C模块引脚描述引脚号miniPCIE引脚名模块引脚名I/O功能描述备注1WAKE

    2025年10月1日
    11
  • 苹果一倍图尺寸(iphone11pro屏幕尺寸)

    iphont4s是2倍图但是你画一个粗为0.5的线,iphont4s显示不出来,iphont5s却可以看到一个像素(从截图上看到的)的线来。识别手机机型使用的是几倍图,一般通过这个值来识别:[UIScreenmainScreen].scale。若为1就1倍图(iphone4/iphone4s是个例外),若为2就是2倍图,若是3就是3倍图。但是现在iphone4/iphone4s都是…

    2022年4月11日
    195
  • 踩坑记录 Lists.newArrayList()

    踩坑记录 Lists.newArrayList()Lists newArrayList

    2026年3月17日
    1
  • lombok插件介绍「建议收藏」

    lombok插件介绍「建议收藏」Lombok项目是一个java库,它可以自动插入到编辑器和构建工具中,增强java的性能。不要再写另一个getter或equals方法,只要有一个注释,你的类就有一个功能齐全的构建器,自动记录变量等等。lombok插件大大减少了java开发的工作量,让程序员更加关注业务逻辑的实现。实现的方法举例:get/set/toString/equals/hashCode/无参构造函数/全参构造函数等。lombok插件注解@Data//data是lombok使用最多的注解,自动生成get/set/

    2025年10月2日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号