LeetCode #43字符串相乘

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);
    }

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值