【leetcode】Multiply Strings
题目:给定两个表示大数的字符串。求乘积,这里仅仅针对正数。
分析:開始的时候打算一位一位的算。按着笔算的形式。可是写着写着发现太麻烦,后来在网上找到计算乘法的令一种技巧,感觉简洁多了。
先看代码,再分析。
string multiply(string num1, string num2) {
if(num1 == "0" || num2 == "0")
return "0";
//start from unit
reverse(num1.begin(), num1.end());
reverse(num2.begin(), num2.end());
int lenNum1 = num1.size();
int lenNum2 = num2.size();
vector<int> num_re(lenNum1 + lenNum2, 0);
for (int i = lenNum1 - 1; i >= 0; --i)
for (int j = lenNum2 - 1; j >= 0; --j)
{
//it's a skill.
num_re[i + j] += (num1[i] - '0') * (num2[j] - '0');
}
//from low -> high
int carry = 0;
for (int i = 0; i < lenNum1 + lenNum2; ++i)
{
num_re[i] += carry;
carry = num_re[i]/10;
num_re[i] %= 10;
}
//change to string
string str_re(lenNum2 + lenNum1,0);
for (int i = 0; i < lenNum1 + lenNum2; ++i)
{
str_re[i] = num_re[i] + '0';
}
//the highest unit may be 0, skip them or it.
int lastNot0 = str_re.find_last_not_of('0');
str_re = str_re.substr(0, lastNot0 + 1);
reverse(str_re.begin(), str_re.end());
return str_re;
}程序的開始处将给定的字符串翻转。一是顺应我们的习惯。我们总是习惯从数组下标0開始处理。第二点非常重要。看下图:
所以我们逆置后。高位就放在了后面,这样产生的进位就能够向后移动。
文章開始提到计算乘法的技巧:
for (int j = lenNum2 - 1; j >= 0; --j)
{
//it's a skill.
num_re[i + j] += (num1[i] - '0') * (num2[j] - '0');
}首先,num_re中的元素类型为int。就不会发生溢出,其次。用i + j确定其终于的位置。这就方便了非常多。
再说下跳过一些0是什么情况,我们初始的结果数组是两个乘数的长度和,但有可能没产生进位,比方 1 * 2 = 2,结果为1位,但结果数组确是2位,所以高位的0应该忽略。否则返回的结果就是02。
浙公网安备 33010602011771号