题目描述
有两个用字符串表示的非常大的大整数,算出他们的乘积,也是用字符串表示。不能用系统自带的大整数类型。
输入描述:
空格分隔的两个字符串,代表输入的两个大整数
输出描述:
输入的乘积,用字符串表示
示例1
输入
72106547548473106236 982161082972751393
输出
70820244829634538040848656466105986748
思路
方法来源:http://www.cnblogs.com/TenosDoIt/p/3735309.html
方法就是和我们手工做乘法相同,只是这里不处理进位,最后统一处理。从上面的图片可以看出。
两数相乘,结果最多有n1+n2位。
再相乘的过程中,两个数所有位分别相乘,保存在第 i+j 位,这里为了方便处理,将其倒转过来保存,低位保存在前,高位保存在后。
解答
#include<iostream>
#include<vector>
#include<string>
using namespace std;
string fun(const string &str1,const string &str2)
{
int n1=str1.size(),n2=str2.size();
vector<int> temp(n1+n2,0);
int k=n1+n2-2;
for(int i=0;i<n1;i++)
for(int j=0;j<n2;++j)
temp[k-i-j]+=(str1[i]-'0')*(str2[j]-'0');//此处是核心
int carry=0;
for(int i=0;i<n1+n2;++i)//处理进位
{
temp[i]=carry+temp[i];
carry=temp[i]/10;
temp[i]=temp[i]%10;
}
int u=n1+n2-1;
while(temp[u]==0)//将头部的零去掉
u--;
string res;
for(int i=u;i>=0;i--)//再拼接为字符串
res+=temp[i]+'0';
return res;
}
int main()
{
string str1,str2;
cin>>str1>>str2;
string res=fun(str1,str2);
cout<<res<<endl;
return 0;
}
另外,leetcode43的做法:
class Solution {
public:
string multiply(string num1, string num2) {
auto l1=num1.size(); auto l2=num2.size();
string res(l1+l2,'0');
/*
此处的做法是将乘法运算的相乘和错位相加合并在一起处理,进位包含了相乘的进位和相加的进位
思考起来比较复杂,而且最终结果的位对应思考起来比较费劲
*/
for(int i=l1-1;i>=0;i--) //乘法运算在下面的乘数
{
int add=0; //add用于作为向高位的进位
for(int j=l2-1;j>=0;j--)
{
int mul=(num1[i]-'0')*(num2[j]-'0');
int sum=res[i+j+1]-'0'+add+mul%10;
res[i+j+1]=sum%10+'0';
add=sum/10+mul/10;
}
//最后还有一个进位没有处理,加到第i位
res[i]+=add;
}
for(int i=0;i<l1+l2;++i)
{
if(res[i]!='0')
return res.substr(i);
}
return "0";
}
};