1.背景知识
1.1 String,StringBuffer,StringConstructor
String类是不可变类。StringBuffer和StringConstructor是可变类,字符串内的字符可以被修改。
StringBuffer是线程安全的,使用了Synchronized关键词,加了线程锁。
StringConstructor不是线程安全的,所以效率比StringBuffer稍高。
StringBuffer和StringConstructor两者功能类似。
具体详见 https://blog.csdn.net/csxypr/article/details/92378336
1.2 竖式乘法以及优化竖式乘法
1.2.1 普通竖式乘法
普通竖式乘法的思想十分的简单:遍历num2的每一个数字与num1相乘,将结果补零后进行加和,实际上是字符串的相加问题。
1.2.2 优化竖式乘法
优化竖式乘法:在本质上也是一种特殊的规律。优化竖式乘法的每一个加项是由一位与一位的乘积得出的,乘积的结果按两位显示(xy或者是0z)。以上图为例:其规则:
5x3=15,放在第一行;5x2=10;放在第二行,左移一位(补零);5x1=05,左移一位。5乘num1的各位完毕。然后对4,再进行如上操作。
创建一个int类型的数组rs。可以发现有如下规律:
num1的第i位乘以num2的第j位的乘积,加上之前的进位,正好位于结果的i+j+1位,即:
rs[i+j+1]=(rs[i+j+1]+num1的第i位*num2的第j位)%10
同时有:进位保存在rs[i+j]中。
rs[i+j]=(rs[i+j+1]+num1的第i位*num2的第j位)/10
由于计算是从i=0;j=0;自底向上进行计算的,所以rs的赋值过程类似于DP动态规划。
2.Java代码实现
2.1 普通竖式乘法
//采用普通竖式乘法的思想
//Version2
//Code By Codefmeister
public class StringMultiple_43_version2 {
public static String multiply(String num1,String num2){
if(num1.equals("0")||num2.equals("0")){
return "0";
}
else{
String rs="0";
//num2的每一个数去乘以num1,再加和
for(int i=num2.length()-1;i>=0;i--){
StringBuilder temp = new StringBuilder();
int carry = 0;
int currentNum2Bit = num2.charAt(i)-'0';
for(int j=0;j<num2.length()-1-i;j++){
temp.append('0');
}
for(int k=num1.length()-1;k>=0||carry!=0;k--){
int currentNum1Bit = k<0?0:num1.charAt(k)-'0';
char bitRs = (char)(((currentNum1Bit*currentNum2Bit)+carry)%10+'0');
carry = (currentNum1Bit*currentNum2Bit+carry)/10;
temp.append(bitRs);
}
rs = addString(rs,temp.reverse().toString());
}
return rs;
}
}
public static String addString(String num1,String num2){
StringBuilder addRs = new StringBuilder();
int carry = 0,n=0,m=0;
char tempBit;
for(int i=num1.length()-1,j=num2.length()-1;i>=0 || j>=0 || carry>0;i--,j--){
n = i<0?0 : num1.charAt(i) - '0';
m = j<0?0 : num2.charAt(j) - '0';
tempBit = (char)((n+m+carry)%10+'0');
carry = (n+m+carry)/10;
addRs.append(tempBit);
}
return addRs.reverse().toString();
}
public static void main(String args[]){
String a="9";
String b = "9";
String rs = "0";
rs = multiply(a,b);
System.out.println(rs);
}
}
2.2 优化竖式乘法
//采用优化竖式乘法
//Version3
//Code By Codefmeister
public class StringMultiple_43_version3 {
public static String multiply(String num1,String num2){
if(num1.equals("0")||num2.equals("0")){
return "0";
}
int num1Bit=0,num2Bit=0,sum=0;
int[] rs = new int[num1.length()+num2.length()];
for(int i = num1.length()-1;i>=0;i--){
num1Bit = num1.charAt(i)-'0';
for(int j = num2.length()-1;j>=0;j--){
num2Bit = num2.charAt(j)-'0';
sum = num1Bit*num2Bit+rs[i+j+1];
rs[i+j+1] = sum%10;
rs[i+j] = sum/10+rs[i+j];
}
}
StringBuilder StringRs = new StringBuilder();
char p;
for(int i=0;i<num1.length()+num2.length();i++){
p = (char)(rs[i]+'0');
if(i==0&&rs[i]==0){
continue;
}
StringRs.append(p);
}
return StringRs.toString();
}
public static void main(String args[]){
String a="123";
String b="456";
String rs = multiply(a,b);
System.out.println(rs);
}
}