一、 大整数乘法(multiplication of large integers)
(1) 模拟多位数乘法时列竖式进行计算的方法
(2) 例子:
① 1233*234
1 | 2 | 3 | 3 | |
2 | 4 | 6 | 6 | 2 |
3 | 6 | 9 | 9 | 3 |
4 | 8 | 12 | 12 | 4 |
2 | 4 | 6 | 6 | ||
3 | 6 | 9 | 9 | ||
4 | 8 | 12 | 12 | ||
2 | 7 | 16 | 23 | 21 | 12 |
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位分为节,列出乘法表,将斜线间的数字相加② 改进:(也可以是每两位为一节,看实际情况而定)
8 | 216 | 547 | |
768 | 20736 | 52512 | 96 |
6250 | 169560 | 429395 | 785 |
768 | 20736 | 52512 | |
6250 | 169560 | 429395 | |
768 | 27016 | 222072 | 429395 |
将表中最后一行进行如下处理:从个位数开始,每一个方格里只保留三个数字,超出1000的部分进位到前一个方格里:
| 768 | 27016 | 222072 | 429395 |
| 768+27=795 | 27016+222=27238 | 222072+429=222501 | 留395进429 |
| 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;
}