avatar

目录
43字符串相乘

题目链接

题目描述:

给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。

示例 1:

输入: num1 = “2”, num2 = “3”
输出: “6”

示例 2:

输入: num1 = “123”, num2 = “456”
输出: “56088”

说明:

num1 和 num2 的长度小于110。
num1 和 num2 只包含数字 0-9。
num1 和 num2 均不以零开头,除非是数字 0 本身。
不能使用任何标准库的大数类型(比如 BigInteger)或直接将输入转换为整数来处理。


解题思路

  本题难点在于如何复原我们日常的思维方式,也就是从小就会的竖式相乘法。这里仅提供一个暴力法,上图~
在这里插入图片描述

  由图可知,实际上就是遍历num2数字,使之与num1相乘,最后将结果累加。
  在逐项相乘部分,要考虑一个问题——补0。而包括逐项相乘和逐项累加都是#415.字符串相加的延续,题解在此~
  简单来说,无论乘法还是加法都要考虑三个问题:

  1. 进位问题,carry = (n1 * n2 + carry) / 10carry = (n1 + n2 + carry) / 10均表示当前位相乘或相加后的进位结果;
  2. 最高位溢出问题,这里包含两部分。是如果最高位计算完成后也发生了进位情况应该怎么办?可以在for循环中添加carry != 0,那么这就会引发第二个问题,如果ij已经遍历完毕了怎么办?这时可以用一个三目运算符解决问题n1 = j < 0 ? 0 : num1[j] - '0'
  3. 当前位计算问题,当然是product = (n1 * n2 + carry) % 10并将结果添加到temp末尾

  另外要注意,循环结束后结果是倒叙的,需要先reverse以下再进行计算~


代码

cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class Solution {
public:
string multiply(string num1, string num2) {
if(num1 == "0" || num2 == "0")
return "0";

string result = "";
for(int i = num2.size() - 1; i >= 0; i--){
int carry = 0;
string temp = "";
//补0
for(int j = 0; j < num2.size() - 1 - i; j++){
temp += '0';
}
int n2 = num2[i] - '0';
for(int j = num1.size() - 1; j >= 0 || carry != 0; j--){
int n1 = j < 0 ? 0 : num1[j] - '0';
int product = (n1 * n2 + carry) % 10;
temp += to_string(product);
carry = (n1 * n2 + carry) / 10;
}
reverse(temp.begin(), temp.end());
result = addString(result, temp);
}

return result;
}

string addString(string num1, string num2){
string result = "";
int carry = 0;
for(int i = num1.size() - 1, j = num2.size() - 1; i >= 0 || j >= 0 || carry != 0; i--, j--){
int n1 = i < 0 ? 0 : num1[i] - '0';
int n2 = j < 0 ? 0 : num2[j] - '0';
int temp = (n1 + n2 + carry) % 10;
result += to_string(temp);
carry = (n1 + n2 + carry) / 10;
}
reverse(result.begin(), result.end());
return result;
}
};

如果有错误或者不严谨的地方,请务必给予指正,十分感谢。

文章作者: breadhunter
文章链接: http://yoursite.com/2020/03/20/43%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9B%B8%E4%B9%98/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 breadhunter
打赏
  • 微信
    微信
  • 支付寶
    支付寶