给定两个以字符串形式表示的非负整数 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)或直接将输入转换为整数来处理。
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/multiply-strings
方法一:普通竖式
public static String multiply1(String num1, String num2) {
//1.如果num1或num2为"0"
if (num1.equals("0") || num2.equals("0")) return "0";
//2.不为"0"的情况下,把num2的每一位与num1相乘
//保存计算结果
String result = "";
for (int i = num2.length() - 1; i >= 0; i--) {
StringBuilder str = new StringBuilder();
//2.1除了num2第一位,后面每一位与都需要补零
for (int j = 0; j < num2.length() - 1 - i; j++) {
str.append('0');
}
int carry = 0;
int n2 = num2.charAt(i) - '0';
// num2 的第 i 位数字 n2 与 num1 相乘
for (int j = num1.length() - 1; j >= 0; j--) {
int n1 = num1.charAt(j) - '0';
int tmp = n2 * n1 + carry;
carry = tmp / 10;
str.append((char) (tmp % 10 + '0'));
}
if (carry != 0) str.append((char) (carry + '0'));
// 将当前结果与新计算的结果求和作为新的结果
result = addStrings(result, str.reverse().toString());
}
return result;
}
//字符串相加
public static String addStrings(String num1, String num2) {
StringBuilder str = new StringBuilder();
int i = num1.length() - 1;
int j = num2.length() - 1;
int carry = 0, tmp;
while (i >= 0 || j >= 0) {
int n1 = i >= 0 ? num1.charAt(i) - '0' : 0;
int n2 = j >= 0 ? num2.charAt(j) - '0' : 0;
tmp = n1 + n2 + carry;
if (tmp / 10 == 1) carry = 1;
else carry = 0;
str.append((char) (tmp % 10 + '0'));
i--;
j--;
}
if (carry == 1) str.append('1');
return str.reverse().toString();
}
方法二:优化竖式
该算法是通过两数相乘时,乘数某位与被乘数某位相乘,与产生结果的位置的规律来完成。具体规律如下: 乘数 num1 位数为 MM,被乘数
num2 位数为 NN, num1 x num2 结果 res 最大总位数为 M+N num1[i] x num2[j] 的结果为
tmp(位数为两位,“0x”,"xy"的形式),其第一位位于 res[i+j],第二位位于 res[i+j+1]。
public static String multiply2(String num1, String num2) {
if (num1.equals("0") || num2.equals("0")) return "0";
int[] res = new int[num1.length() + num2.length()];
for (int i = 0; i < num1.length(); i++) {
int n1 = num1.charAt(i) - '0';
for (int j = 0; j < num2.length(); j++) {
int n2 = num2.charAt(j) - '0';
int tmp = n1 * n2;
res[i + j] += tmp / 10;
res[i + j + 1] += tmp % 10;
}
}
int carry = 0;
StringBuilder str = new StringBuilder();
for (int i = num1.length() + num2.length() - 1; i >= 0; i--) {
if (i == 0 && res[i] == 0) continue;
str.append((char) (res[i] + carry) % 10);
carry = (res[i] + carry) / 10;
}
return str.toString();
}