栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

大整数乘法(分治)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

大整数乘法(分治)

最近算法课要求实现大整数乘法,于是有了这篇博客。

思路

普通高精度乘法即模拟竖式乘法运算,一个数的每一位都与另一个数的每一位相乘,复杂度O(n^2),考虑分治,将一个大整数分成两部分,两部分分别处理后再相加;

设X=A*10^n/2+B ,Y=C*10^n/2+D,则XY=(A*10^n/2+B)(C*10^n/2+D)=AC*10^n+(AD+CB)*10^n/2+BD ;

但这样并没有优化时间复杂度,对AD+BC进行分解优化后得:

XY=AC*10^n+[(A-B)(D-C)+AC+BD]*10^n/2+BD;

每次要进行三次乘法,六次加减法,两次移位操作,复杂度降至O(n^1.59)。

代码:
#pragma GCC optimize(2)
#include 
using namespace std;
typedef long long ll;
//大整数符号和数值分开处理 
struct node{
	string s; 
	int f,siz;
	node(){ s=""; f=1; siz=0;}
};

node add(node a,node b);
//初始化 
void init(node &a){
	if(a.s[0]=='-'){
		a.s.erase(a.s.begin()); a.f=-1;
	}
	else a.f=1;
	a.siz=a.s.size();
}
//打印函数 
void print(node x){
	int i=0;
	while(x.s[i]=='0') i++;
	if(i==x.siz){ cout<<0<<"n"; return ;}
	if(x.f==-1) cout<<"-";
	for(;i1&&a.s[0]=='0'){
		a.s.erase(a.s.begin()); a.siz--;
	} 
}
//将两个大整数通过补零,实现位数相同 
void lead_add(node &a,node &b){
	int cnt=max(a.siz,b.siz);
	reverse(a.s.begin(),a.s.end());
	while(a.siz=0;i--){
			if(a.s[i]>b.s[i]) break;
			if(a.s[i]=10){
			ans.s+='0'+tmp+jin-10; jin=1;
		}
		else{
			ans.s+='0'+tmp+jin; jin=0;
		}
	}
	if(jin) ans.s+='0'+1;
	reverse(ans.s.begin(),ans.s.end());
	lead_sub(ans);
	ans.siz=ans.s.size();
	return ans;
}
//判断该数是否为零 
bool check(node a){
	lead_sub(a);
	if(a.s=="0") return true;
	return false;
}
//乘法 
node mul(node A,node B){
	node ans;
	lead_add(A,B);
	ans.f=A.f*B.f;
	//若其中一个数位0,直接返回0 
	if(check(A)||check(B)){ans.s="0"; ans.siz=1; return ans;}
	//位数为1,直接计算 
	if(A.siz==1){
		int tmp=(A.s[0]-'0')*(B.s[0]-'0');
		if(tmp/10){ ans.s+='0'+tmp/10; ans.siz++;}
		ans.s+='0'+tmp%10; ans.siz++;
		return ans;
	}
	lead_add(A,B);
	int len=A.siz/2;
	node a,b,c,d,e,f;
	a.f=b.f=c.f=d.f=1;
	//拆分 
	a.s=A.s.substr(0,len);
	b.s=A.s.substr(len);
	c.s=B.s.substr(0,len);
	d.s=B.s.substr(len);
	init(a); init(b); init(c); init(d);
	//共进行三次乘法,六次加减法,两次移位操作 
	e=sub(a,b);
	f=sub(d,c);
	a=mul(a,c);  
	e=mul(e,f);
	b=mul(b,d);
	e=add(e,a);
	e=add(e,b);
	for(int i=1;i<=2*(A.siz-len);i++){
		a.s+='0'; a.siz++;
		if(i<=A.siz-len){ e.s+='0'; e.siz++;}
	}
	ans=add(a,e); ans=add(ans,b);
	ans.f*=A.f*B.f;
	return ans;
}

int main()
{
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	node a,b;
	cin>>a.s>>b.s;
	init(a); init(b);
	node ans=mul(a,b);
	print(ans);
	return 0;
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/291195.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号