矩阵相乘简单递归实现by24k

算法导论课后习题要求写一个最简单的2的n此方的矩阵相乘算法:

本代码测试环境为win10下的VC6.0,目前仅能计算2的n此方的方阵且A,B方阵的阶数必须相同。实际上源码仅能计算两个4*4阶矩阵相乘,想要计算2*2或8*8或16*16等等的矩阵需要手工调整几个参数,但这并不妨碍表现递归算法到C语言的转化核心--如何计算正确的坐标

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #define M1 (p1->w-p1->x+1)
  4 #define N1 (p1->z-p1->y+1)
  5 #define M2 (p2->w-p2->x+1)
  6 #define N2 (p2->z-p2->y+1)
  7 typedef struct m
  8 {
  9     int x,y,w,z;//左上角坐标(x,y)右下角坐标(w,z);确定数组大小,为实际坐标
 10 }M;
 11 typedef struct ret 
 12 {
 13     int c[4][4];
 14 }R;
 15 R *Matrix_Multiply(M *p1,M *p2,int A[][4],int B[][4])
 16 {
 17     int i,j,l=0,k=0;
 18     R *r=(R*)malloc(sizeof(R));
 19     r->c[0][0]=0;
 20     R *r1[8];
 21     for(l=0;l<8;l++)
 22     r1[l]=(R*)malloc(sizeof(R));
 23     M *m1,*m2;
 24     m1=m2=NULL;
 25     m1=(M*)malloc(sizeof(M));
 26     m2=(M*)malloc(sizeof(M));
 27     if(M1==1&&N1==1&&M2==1&&N2==1)
 28     {
 29         r->c[0][0]=A[p1->x][p1->y]*B[p2->x][p2->y];
 30         return r;
 31     }
 32     else
 33     {
 34         ///c11=a11*b11+a12*b21//
 35 //a11
 36         m1->x=p1->x;
 37         m1->y=p1->y;
 38         m1->w=p1->x+M1/2-1;
 39         m1->z=p1->y+N1/2-1;
 40 //b11
 41         m2->x=p2->x;
 42         m2->y=p2->y;
 43         m2->w=p2->x+M2/2-1;
 44         m2->z=p2->y+N2/2-1;
 45 
 46         r1[0]=Matrix_Multiply(m1,m2,A,B);
 47 
 48 //a12
 49         m1->x=p1->x;        
 50         m1->y=p1->y+N1/2;    
 51         m1->w=p1->x+M1/2-1;    
 52         m1->z=p1->y+N1-1;
 53 
 54 //b21
 55         m2->x=p2->x+M2/2;
 56         m2->y=p2->y;
 57         m2->w=p2->x+M2-1;
 58         m2->z=p2->y+N2/2-1;
 59 
 60         r1[1]=Matrix_Multiply(m1,m2,A,B);
 61 ///sum a11*b11 and a12*b21
 62         for(i=0;i<M1/2;i++)
 63             for(j=0;j<N2/2;j++)
 64             {
 65         r->c[i][j]=r1[0]->c[i][j]+r1[1]->c[i][j];
 66             }
 67         c12=a11*b12+a12*b22////
 68 //a11
 69         m1->x=p1->x;
 70         m1->y=p1->y;
 71         m1->w=p1->x+M1/2-1;
 72         m1->z=p1->y+N1/2-1;
 73 
 74 //b12
 75         m2->x=p2->x;
 76         m2->y=p2->y+N2/2;
 77         m2->w=p2->x+M2/2-1;
 78         m2->z=p2->y+N2-1;
 79 
 80         r1[2]=Matrix_Multiply(m1,m2,A,B);
 81 
 82 //a12
 83         m1->x=p1->x;        
 84         m1->y=p1->y+N1/2;    
 85         m1->w=p1->x+M1/2-1;    
 86         m1->z=p1->y+N1-1;
 87 //b22
 88         m2->x=p2->x+M2/2;
 89         m2->y=p2->y+N2/2;
 90         m2->w=p2->x+M2-1;
 91         m2->z=p2->y+N2-1;
 92         r1[3]=Matrix_Multiply(m1,m2,A,B);
 93         
 94         for(i=0;i<M1/2;i++)
 95             for(j=0;j<N2/2;j++)
 96             {
 97                 r->c[i][N2/2+j]=r1[2]->c[i][j]+r1[3]->c[i][j];
 98             }
 99         c21=a21*b11+a22*b21//
100         
101 //a21
102         m1->x=p1->x+M1/2;
103         m1->y=p1->y;
104         m1->w=p1->x+M1-1;
105         m1->z=p1->y+N1/2-1;    
106 
107 //b11
108         m2->x=p2->x;
109         m2->y=p2->y;
110         m2->w=p2->x+M2/2-1;
111         m2->z=p2->y+N2/2-1;
112 
113         r1[4]=Matrix_Multiply(m1,m2,A,B);
114 
115 //a22
116         m1->x=p1->x+M1/2;
117         m1->y=p1->y+N1/2;
118         m1->w=p1->x+M1-1;
119         m1->z=p1->y+N1-1;
120 //b21
121         m2->x=p2->x+M2/2;
122         m2->y=p2->y;
123         m2->w=p2->x+M2-1;
124         m2->z=p2->y+N2/2-1;
125 
126 
127         r1[5]=Matrix_Multiply(m1,m2,A,B);
128 
129         for(i=0;i<M1/2;i++)
130             for(j=0;j<N2/2;j++)
131                 r->c[M1/2+i][j]=r1[4]->c[i][j]+r1[5]->c[i][j];
132 
133         ///c22=a21*b12+a22*b22//
134 
135 //a21
136         m1->x=p1->x+M1/2;
137         m1->y=p1->y;
138         m1->w=p1->x+M1-1;
139         m1->z=p1->y+N1/2-1;
140 
141 //b12
142         m2->x=p2->x;
143         m2->y=p2->y+N2/2;
144         m2->w=p2->x+M2/2-1;
145         m2->z=p2->y+N2-1;
146 
147         r1[6]=Matrix_Multiply(m1,m2,A,B);
148 
149 //a22
150         m1->x=p1->x+M1/2;
151         m1->y=p1->y+N1/2;
152         m1->w=p1->x+M1-1;
153         m1->z=p1->y+N1-1;
154 
155 //b22
156         m2->x=p2->x+M2/2;
157         m2->y=p2->y+N2/2;
158         m2->w=p2->x+M2-1;
159         m2->z=p2->y+N2-1;
160 
161         r1[7]=Matrix_Multiply(m1,m2,A,B);
162 
163         for(i=0;i<M1/2;i++)
164             for(j=0;j<N2/2;j++)
165                 r->c[M1/2+i][N2/2+j]=r1[6]->c[i][j]+r1[7]->c[i][j];
166         for(i=0;i<8;i++)
167             free(r1[i]);
168         free(m1);
169         free(m2);
170         return r;
171     }
172 }
173 int main()
174 {
175     int A[4][4]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16},B[4][4]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
176     R *pr=(R*)malloc(sizeof(R));
177     M *p1,*p2;
178     p1=(M*)malloc(sizeof(M));
179     p2=(M*)malloc(sizeof(M));
180     p1->x=p1->y=p2->x=p2->y=0;
181     p1->w=p1->z=p2->w=p2->z=3;
182     pr=Matrix_Multiply(p1,p2,A,B);
183 
184     for(int i=0;i<4;i++)
185     {
186         for(int j=0;j<4;j++)
187         {
188             printf("%4d ",pr->c[i][j]);//右对齐输出
189         }
190         printf("\n");
191     }
192     free(pr);
193     free(p1);
194     free(p2);
195     return 0;
196 }
View Code

计算正确的坐标:左上角实际坐标加上合适的offset(偏移量)

for exmple:我们已知A为M*N的矩阵左上角坐标为(x1,y1),计算一下拆分后的矩阵A12的左上角坐标(A12->x1,A12->y1)和右下角的坐标(A12->x2,A12->y2)

A12->x1=A->x1

A12->y1=A->y1+N/2

A12->x2=A->x1+M/2-1

A12->y2=A->y1+N-1

By Ken W.Black 山东科技大学 2017/11/7

本人学生,这是我第一篇博客,如有错误,敬请斧正,感激不尽

转载于:https://www.cnblogs.com/kenwblack/p/7801083.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值