分治法 大数乘法

不知道有没有更高效的算法

#include "stdio.h"
 #include "stdlib.h"
 
 #define M 100
 
 typedef struct _Node{
 	int s[M];
 	int l;
 	int c;
 }Node, *pNode;
 
 void cp(pNode src, pNode des, int st, int l){
 	int i, j;
 	for(i=st, j=0; i<st+l; i++, j++){
 		des->s[j] = src->s[i];
 	}
 	des->l = l;
 	des->c = st + src->c;
 }
 
 /*
 分治法 大数乘法
 X = A*10^n + B
 Y = C*10^m + D
 X*Y = A*C*10^(n+m) + A*D*10^n + B*C*10^m + B*D
 */
 
 void add(pNode pa, pNode pb, pNode ans){
 	int i, c;
 	int ta, tb;
 	pNode k;
 
 	if(pa->c < pb->c){
 		k = pa; pa = pb; pb = k;
 	}
 	ans->c = pb->c;
 	c = 0;
 	for(i=0; i<pa->l+pa->c-pb->c; i++){
 		if(i<pa->c-pb->c)
 			ta = 0;
 		else
 			ta = pa->s[i-(pa->c-pb->c)];
 		if(i>=pb->l)
 			tb = 0;
 		else
 			tb = pb->s[i];
 		ans->s[i] = (ta + tb + c)%10;
 		c = (ta + tb + c)/10;
 	}
 	if(c)
 		ans->s[i++] = 1;
 	ans->l = i;
 }
 
 void mul(pNode pa, pNode pb, pNode ans){
 	int i, c, w;
 	int ma = pa->l>>1, mb = pb->l>>1;
 	Node ah, al, bh, bl;
 	Node t1, t2, t3, t4, z;
 	pNode k;
 
 	if(!ma || !mb){
 		if(!ma){
 			k = pa; pa = pb; pb = k;
 		}
 		
 		ans->c = pa->c + pb->c;
 		w = pb->s[0];
 		c = 0;
 		for(i=0; i<pa->l; i++){
 			ans->s[i] = (w*pa->s[i] + c)%10;
 			c = (w*pa->s[i] + c)/10;
 		}
 		if(c) ans->s[i++] = c;
 		ans->l = i;
 		return;
 	}
 
 	cp(pa, &ah, ma, pa->l-ma);
 	cp(pa, &al, 0, ma);
 	cp(pb, &bh, mb, pb->l-mb);
 	cp(pb, &bl, 0, mb);
 	
 	mul(&ah, &bh, &t1);
 	mul(&ah, &bl, &t2);
 	mul(&al, &bh, &t3);
 	mul(&al, &bl, &t4);
 
 	add(&t3, &t4, ans);
 	add(&t2, ans, &z);
 	add(&t1, &z, ans);
 
 }
 
 int main(){
 	Node ans;
 	int i;
 	//54321 * 543
 	Node a = {{1, 2, 3, 4, 5}, 5, 0};
 	Node b = {{3, 4, 5}, 3, 0};
 	mul(&a, &b, &ans);
 	for(i=ans.l-1; i>=0; i--)
 		printf("%d", ans.s[i]);
 	printf("\n");
 	return 0;
 }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值