分治算法——大整数乘法(multiplication of large integers)

一、     大整数乘法(multiplication of large integers)

(1)  模拟多位数乘法时列竖式进行计算的方法

(2)  例子:

①  1233*234

1233 
24662
36993
4812124

2466  
 3699 
  481212
2716232112

 

2

7

16

23

21

12

2+0=2

7+1=8

16+2=18

23+2=25

21+1=22

 

2

留8进0

留8进1

留5进2

留2进2

留2进1

2

8

8

5

2

2

②改进:

8216547*96785将两数从个位起,每3位分为节,列出乘法表,将斜线间的数字相加②  改进:(也可以是每两位为一节,看实际情况而定)

8216547 
768207365251296
6250169560429395785
7682073652512 
 6250169560429395
76827016222072429395

将表中最后一行进行如下处理:从个位数开始,每一个方格里只保留三个数字,超出1000的部分进位到前一个方格里:

 

768

27016

222072

429395

 

768+27=795

27016+222=27238

222072+429=222501

395429

 

795

238

501

39582

所以8216547*96785 = 79523850139582

// 大整数乘法 (基础版)
//大整数乘法例① 

#include<iostream>
using namespace std;

string MulOfLargeInt(string a , string b)
{
	int lena=a.size(),lenb=b.size();  
	int mul[lenb][lena];         // 用二维数组来存每位数相乘的结果 
	for(int i=0;i<lena;i++){
		for(int j=0;j<lenb;j++){
			int A ,B ;
			A = a[i]-'0';
			B = b[j]-'0';
			mul[j][i]=A*B;
		}
	}
	int sum[lenb+lena];    // 存相加的结果,m位数和n位数相乘结果是m+n位数或m+n-1位数 
	sum[0]=0;
	int p=0,q=0,k=1,s=0,p1,q1;           // P:行 q:列 
	while(p<lenb&&q<lena){
		p1=p;
		q1=q;
		s=mul[p1][q1];                 // 斜对角线上的元素相加 
		while(1){
			if((p1+1)<lenb && (q1-1)>=0){
				p1++;
				q1--;
				s+=mul[p1][q1];
			}else break;
		}
		sum[k]=s; 
		k++;
		if(q<lena-1) q++;
		else if(q==lena-1){
			p++;
		} 
	}
	int carry=0;
	for(int i=lenb+lena-1;i>0;i--){
		if(sum[i]>=10){
			carry=sum[i]/10;             // 保留低位,高位进位 
			sum[i] = sum[i]%10;
			sum[i-1]+=carry;
		}
	}
	string ans;
	int h;
	if(sum[0]==0) h=1;
	else h=0;
	for(int i=h;i<lenb+lena;i++){
	
		ans+=sum[i]+'0';
	} 
	return ans;
}

int main()
{
	string a , b ,ans ;
	cin >> a >> b;
	ans = MulOfLargeInt(a , b);
	cout << ans << endl;
	return 0;
} 

// 大整数乘法改进版
//大整数乘法例① 

#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;

string MulOfLargeInt(string a , string b)
{
	int lena=a.size(),lenb=b.size();  
	// 将string型的数转成int类型的数组 
	for(int i=0;i<lena;i++){
		a[i]=a[i]-'0';
	}
	for(int i=0;i<lenb;i++){
		b[i]=b[i]-'0';
	}
	int sum[lenb+lena];    // 存相加的结果,m位数和n位数相乘结果是m+n位数或m+n-1位数 
	sum[0]=0;
	memset(sum,0,sizeof(sum));
	int p=lenb-1,q=lena-1,k=lenb+lena-1,s=0,p1,q1,carry;           // P:行 q:列 
	string ans;
	while(p>=0&&q>=0){
		p1=p;
		q1=q;
		s=b[p1]*a[q1];                 // 斜对角线上的元素相加 
		while(1){
			if((p1+1)<lenb && (q1-1)>=0){
				p1++;
				q1--;
				s+=a[q1]*b[p1];
			}else break;
		}
		sum[k]+=s;
		if(sum[k]>=10){
			carry=sum[k]/10;             // 保留低位,高位进位 
			sum[k]=sum[k]%10;	
		}
		else carry=0;
		sum[k-1]+=carry;
		char ch=sum[k]+'0';
		ans=ch+ans;
		k--;
		if(p>0) p--;
		else if(p==0){
			q--;
		} 
	}
	string s1;
	if(sum[0]!=0){
		 s1= sum[0]+'0';
		 ans = s1+ans;
	}
	return ans;
}

int main()
{
	string a , b ,ans ;
	cin >> a >> b;
	ans = MulOfLargeInt(a , b);
	cout << ans << endl;
	return 0;
} 

//大整数乘法例② 

#include<iostream>
#include<string.h>
using namespace std;

void StringInt(string a , int a1[],int len)
{
	int lena=a.size(),k=len-1;
	while(lena>0){
		if(lena>=3){
			a1[k]=(a[lena-1]-'0')+(a[lena-2]-'0')*10+(a[lena-3]-'0')*100;
			lena-=3;
			k--;
		}else{
			if(lena==1){
				a1[k]=a[lena-1]-'0';
				k--;
				lena=0;
			}
			else if(lena==2){
				a1[k]=(a[lena-1]-'0')+(a[lena-2]-'0')*10;
				k--;
				lena=0;
			}
		}
		
	}
}

string IntString(int a)
{
	string ans;
	char ch;
	while(a>0){
		ch=a%10+'0';
		ans=ch+ans;
		a=a/10;
	}
	while(ans.size()<3) ans = '0'+ans;
	return ans;
}

string MulOfLargeInt(string a , string b)
{
	int lena,lenb;  
	if(a.size()%3!=0) lena=a.size()/3+1;
	else lena=a.size();
	if(b.size()%3!=0) lenb=b.size()/3+1;
	else lenb=b.size();
	int a1[lena],b1[lenb];
	// 将string型的数转成int类型的数组 
	StringInt(a , a1,lena);
	StringInt(b , b1,lenb);
	int sum[lenb+lena];    // 存相加的结果,m位数和n位数相乘结果是m+n位数或m+n-1位数 
	sum[0]=0;
	memset(sum,0,sizeof(sum));
	int p=lenb-1,q=lena-1,k=lenb+lena-1,s=0,p1,q1,carry;           // P:行 q:列 
	string ans,str;
	while(p>=0&&q>=0){
		cout << p <<"  " <<  q << endl;
		p1=p;
		q1=q;
		s=b1[p1]*a1[q1];                 // 斜对角线上的元素相加 
		while(1){
			if((p1+1)<lenb && (q1-1)>=0){
				p1++;
				q1--;
				s+=a1[q1]*b1[p1];
			}else break;
		}	
		sum[k]+=s; 
		if(sum[k]>999){
			carry=sum[k]/1000;             // 保留低位,高位进位 
			sum[k] = sum[k]%1000;	
		}
		else carry=0;
		sum[k-1]+=carry;
		str = IntString(sum[k]);
		ans=str+ans;
		k--;
		if(p>0) p--;
		else if(p==0){
			q--;
		} 
	}
	string s1;
	if(sum[0]!=0){
		 s1= IntString(sum[0]);
		 ans = s1+ans;
		 while(ans[0]=='0') ans.erase(0,1);
	}
	return ans;
}

int main()
{
	string a , b ,ans ;
	cin >> a >> b;
	ans = MulOfLargeInt(a , b);
	cout << ans << endl;
	return 0;
} 

    原文作者:大整数乘法问题
    原文地址: https://blog.csdn.net/applehth/article/details/69640466
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞