对于大整数相乘,可以知道,如果n位整数与m位整数相乘,则结果为最大为m+n位,最小为m+n-1位(若乘数有一个为,则输入一个0,不存在输入多个零的情况。如结果也是m+n-1个零)。
可以理解为两个字符串,如num1=“123” ,num2= “45”,高位都是从下标为0开始,则可以认为结果是一定是5位,因为结果是4位的时候,最高位可以为0。
若结果是数组ret,则有num1[i]*num2[j] 的结果(两个一位数相乘,结果为两位数,当结果为一位数时,高位取0)一定在ret[i+j]和ret[i+j+1]上,如:
例: 123 * 45, 123的第1位 2 和45的第0位 4 乘积 08 存放在结果的第[1, 2]位中
index: 0 1 2 3 4
1 2 3
* 4 5
---------
1 5
1 0
0 5
---------
0 6 1 5
1 2
0 8
0 4
---------
0 5 5 3 5
这样我们就可以单独都对每一位进行相乘计算把结果存入相应的index中
则我们可以从两个数的低位乘起,若num1的长度为n1,num2的长度为n2,则结果长度一定为n1+n2(结果的最高位可能为0)
public String multiply(String num1, String num2) {
if(num1.length()==0||num2.length()==0) return "";
int[] ret=new int[num1.length()+num2.length()];//int数组,存放计算结果
for(int i=num1.length()-1;i>=0;i--){//从num1的最低位开始算
for(int j=num2.length()-1;j>=0;j--){//从num2的最低位开始,乘以num2的每一位
int t=(num1.charAt(i)-'0')*(num2.charAt(j)-'0');//计算num1[i]与num2[j]的结果
t+=ret[i+j+1];//将结果与低位原本有的数相加
ret[i+j+1]=t%10;//低位现在的值是t对10取余
ret[i+j]+=t/10;//低位的进位加到高位上,这里高位上的值可能会超过10,但是没有关系,这里的高位是之后另外两数相乘的低位,会先加这个结果再取余,就像上面两步。所以num1和num2从低位开始加就保证了i+j是从小到大的,保证了所有位上的数最终都不过超过10
}
}
StringBuilder sb=new StringBuilder();
int i=0;
while(i<ret.length-1&&ret[i]==0) i++;//如果最后结果前面有多个0,得去掉,这里注意i<ret.length-1而不是i<ret.length是避免结果是只有多个零如"0000"的情况,要保证剩一个零
for(;i<ret.length;i++) sb.append(ret[i]);//将ret数组里的结果拼接成字符串
return sb.toString();
}