8, 43. 字符串相乘
https://leetcode-cn.com/problems/multiply-strings/
思路1: 遍历每一位,然后相乘后,通过字符串相加加和起来就可以了
思路2: 思路1优化,但是我们有位数相乘的结果后,通过自定义数组实现加和
package com.shangguigu.dachang.algrithm.A03_Strings;
import javax.swing.plaf.basic.BasicButtonUI;
import java.util.Arrays;
/**
* @author : 不二
* @date : 2022/4/8-上午9:15
* @desc : 43. 字符串相乘
* https://leetcode-cn.com/problems/multiply-strings/
*
**/
public class A31_multiply {
public static void main(String[] args) {
String num1 = "123", num2 = "456";
String multiply = multiply_v2(num1, num2);
System.out.println("结果是:" + multiply);
}
/**
* 方法2:方法1中,两位相乘之后的数字通过字符串相加得出。但是如果位数比较高,那么时间复杂度就会高了
* 这里简化一下,直接通过预定义数组来进行相加
* @param num1
* @param num2
* @return
*/
public static String multiply_v2(String num1, String num2){
if (num1.equals("0") || num2.equals("0")) {
return "0";
}
int l1 = num1.length()-1;
int l2 = num2.length()-1;
int[] resultArr = new int[num1.length() + num2.length()];
int carry1 = 0;
int carry2 = 0;
for (int i = l1; i >= 0; i--) {
int n1 = num1.charAt(i) - '0';
carry1 = l1 - i;
for (int j = l2; j >= 0; j--) {
int n2 = num2.charAt(j) - '0';
int product = n1 * n2;
carry2 = l2 - j;
int totalCarryPos = carry1 + carry2;
// 找到应该插入的位置
int pos = resultArr.length - totalCarryPos - 1;
int sum = product + resultArr[pos];
System.out.println("当前数据是:" + Arrays.toString(resultArr) + "----" + product + "---" + totalCarryPos);
resultArr[pos] = sum % 10;
// 有个疑问:原先如果有值,这里难道不可能进位吗
// 这里可以进位,只不过高位超过10,就存超过10的数字也没事,最后一轮会把这个超过的数字给进到第一位的,妙啊
resultArr[pos-1] += sum / 10;
// System.out.println("高位当前是:" + resultArr[pos-1]);
/*int inData = product%10;
int inCarry = product / 10;
int lowData = (resultArr[pos] + inData)%10;
int lowCarry = (resultArr[pos] + inData)/10;
int highData = (resultArr[pos-1] + inCarry)%10;
int highCarry = (resultArr[pos-1] + inCarry)/10;
System.out.println("当前数据是:" + Arrays.toString(resultArr) + "----" + product + "---" + totalCarryPos);
resultArr[pos] = lowData;
resultArr[pos-1] = lowCarry + highData;
// 这个不行啊, pos-2位置原先也可能有数字啊
// 这里其实没有多大必要
if (pos - 2 >= 0) {
resultArr[pos-2] += highCarry;
}*/
System.out.println("---");
}
System.out.println("----------- end ");
}
StringBuilder builder = new StringBuilder();
int start = resultArr[0] == 0 ? 1 : 0;
for (int i = start; i < resultArr.length; i++) {
builder.append(resultArr[i]);
}
return builder.toString();
}
/**
* 这个是直接遍历两个字符串的每一位,然后相乘后,直接使用字符串相加
* @param num1
* @param num2
* @return
*/
public static String multiply_v1(String num1, String num2) {
if (num1.equals("0") || num2.equals("0")) {
return "0";
}
int l1 = num1.length()-1;
int l2 = num2.length()-1;
// int step = Math.max(l1, l2);
String result = "0";
int carry1 = 0;
int carry2 = 0;
for (int i = l1; i >= 0; i--) {
System.out.println(num1.charAt(i));
int n1 = num1.charAt(i) - '0';
carry1 = l1 - i;
for (int j = l2; j >= 0; j--) {
System.out.println(num2.charAt(j));
int n2 = num2.charAt(j) - '0';
int value = n1 * n2;
carry2 = l2 - j;
int totalCarry = carry1 + carry2;
System.out.println(value + "-----------" + totalCarry);
StringBuilder b1 = new StringBuilder();
b1.append(value);
for (int k = 0; k < totalCarry; k++) {
b1.append("0");
}
System.out.println("结果是:" + b1);
// 这里是直接调用刚才字符串相加的方法
result = A30_addStrings.addStrings(result, b1.toString());
}
System.out.println("----------- end ");
}
return result;
}
}