给定两个数字123
和456
作为字符串,我希望能够将它们相乘并打印字符串输出。我无法将它们转换为数字,因为它们可能会很长。我有这个问题的工作代码,如下所示
string multiply(string num1, string num2) {
if(num1[0]=='0'||num2[0]=='0') return "0";
int n1(num1.size()), n2(num2.size()), n(n1+n2);
vector<int> r(n,0);
string s(n,'0');
for(size_t i=0;i<n1;++i){
for(size_t j=0;j<n2;++j){
r[i+j+1]+=(num1[i]-'0')*(num2[j]-'0');
}
}
for(size_t i=n-1;i>0;--i){
if(r[i]>9) r[i-1]+=r[i]/10;
s[i] += r[i]%10;
}
s[0]+=r[0];
return s[0]=='0'?string(s.begin()+1,s.end()):s;
}
但我无法弄清楚这种逻辑是如何产生的。为什么我们将产品放在i+j+1
中然后随身携带?这是一些标准的乘法逻辑吗?
答案 0 :(得分:3)
你实际上是在增加一系列数字:
123 * 456
变为[100 + 20 + 3] * [400 + 50 + 6]
如果您乘以100(3位数)和400(3位数),您将获得40000(5 = 3 + 3 - 1
位数)。
现在,您的输入字符串位于num1[0]
位置的100和400以及位于第三位置的num2[0]
,因为它们有3位数字。
40000有5位数字,因此结果4应放在结果的第五个最右侧位置,即位置r[(r.Length) - (3+3-1)]
。
由于r.Length=num1.length+num2.length
这等于r[0 + 0 + 1]
或r[i + j + 1]
这看起来如此陌生的主要原因是因为人类从最右边开始从右到左排序数字,而这个算法从最高位数开始。
之后的进位步骤是必需的,因为该算法的第一部分将生成高于9的数字,即输入3 * 6 = 12
的两个最后数字,但结果将被放入最右边的位置{{ 1}}