大数乘法
大数乘法处理的过程也是分为三部分。
- 存储
- 计算
- 输出
分析
存储与输出与大数加减法方法一致。区别在于中间计算的过程。在平时,我们使用竖式进行乘法计算时,和加法很相似,从低位开始进行计算,也需要考虑进位操作。区别在于,我们将下面一行的数字相乘计算时,是需要进行错位相加的。
这边的关键之处在于如何体现出错位这一位置关系。
第一行 j | 第二行 i | 答案m |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
0 | 2 | 2 |
1 | 0 | 1 |
1 | 1 | 2 |
1 | 2 | 3 |
可观察到m=i+j。搞清楚位置关系后,中间就好处理了。最后我们都是进行一个相加得到答案,我们可以将相加的过程穿插在中间进行处理。
// 乘法计算
// 把第二个数从后往前依次和第一个数进行相乘,最后累加
for(int i=0;i<l2;i++){
for(int j=0;j<l1;j++){
int tmp=n2[i]*n1[j];// 算出相乘的结果
ans[i+j]+=tmp;//累加
//进位处理
ans[i+j+1]+=(ans[i+j]/10);
ans[i+j]=ans[i+j]%10;
}
}
将中间计算部分处理好之后整道题就完成了70%。
完整代码
#include <iostream>
#include <cstring>
using namespace std;
int main(){
char s1[2005]={0},s2[2005]={0};
int n1[20005]={0},n2[2005]={0},ans[4005]={0};
//字符串形式进行输入
cin>>s1>>s2;
// 倒置转换为整数类型
int l1=strlen(s1);
int l2=strlen(s2);
for(int i=0;i<l1;i++){
n1[i]=s1[l1-1-i]-'0';
}
for(int i=0;i<l2;i++){
n2[i]=s2[l2-1-i]-'0';
}
// 乘法计算
// 把第二个数从后往前依次和第一个数进行相乘,最后累加
for(int i=0;i<l2;i++){
for(int j=0;j<l1;j++){
int tmp=n2[i]*n1[j];
ans[i+j]+=tmp;
//进位处理
ans[i+j+1]+=(ans[i+j]/10);
ans[i+j]=ans[i+j]%10;
}
}
// 输出
bool flag=false;
for(int i=l1+l2;i>=0;i--){
if(ans[i]!=0||i==0){
flag=true;
}
if(flag){
cout<<ans[i];
}
}
return 0;
}