20181125_ARTS_W8

Algorithm(至少一個算法題)

415. Add Strings
題目描述:兩個用字符串表示的大數相加
解題思路:思路很簡單,每位相加并用一個數表示進位即可
算法優化:每位相加后都是存到一個int數組的某一個位置,int能表示的范圍為-2147483648至2147483647,其實就可以一次多位相加,int表示的最大范圍為10位,為了保證不越界每次9位相加并考慮進位(9個數9個數為一組)。
優化注意點:按照優化的思路,結果數組每個元素的范圍是0-999999999,而且除了最高位的元素,其他元素要補0補齊9位。
優化之后提交leetcode發現擊敗的百分比反而變小了,這個可能是因為優化只優化了空間復雜度,實現起來反而復雜了很多

實現代碼如下:

/**
 * 描述:大數相加
 * <p>
 * 優化點:參考BigInteger源碼
 * Created by xuery on 2018/11/25.
 */
public class BigDigitPlus {

    public static void main(String[] args) {
        BigInteger bigInteger = new BigInteger("12341243124341243412", 10);
        System.out.println(optimizeAddStrings("6913259244", "71103343"));
    }

    /**
     * 注意點1:雖然不包括前綴0,但是"0"是要考慮的
     * <p>
     * bug1: num1.charAt是Character類型,需要轉換為數字:num1.charAt(i)-'0'
     * bug2: new String(resultArr,0,len), resultArr為int[],不能這么轉,需要借助StringBuilder
     */
    public static String addStrings(String num1, String num2) {
        int len = Math.max(num1.length(), num2.length()) + 1;
        int carry = 0; //進位

        int[] resultArr = new int[len];

        int i = num1.length() - 1, j = num2.length() - 1, index = len - 1;
        while (i >= 0 || j >= 0) {

            if (i < 0) {
                resultArr[index--] = (num2.charAt(j) + carry - '0') % 10;
                carry = (num2.charAt(j--) + carry - '0') / 10;
            } else if (j < 0) {
                resultArr[index--] = (num1.charAt(i) + carry - '0') % 10;
                carry = (num1.charAt(i--) + carry - '0') / 10;
            } else {
                resultArr[index--] = (num1.charAt(i) - '0' + num2.charAt(j) - '0' + carry) % 10;
                carry = (num1.charAt(i--) - '0' + num2.charAt(j--) - '0' + carry) / 10;
            }
        }
        resultArr[0] = carry;

        StringBuilder sb = new StringBuilder(len);
        for (int k = 0; k < len; k++) {
            if (k == 0 && resultArr[0] == 0) {
                continue;
            } else {
                sb.append(resultArr[k]);
            }
        }
        return sb.toString();
    }

    /**
     * 優化方案:適用于num1,num2的位數特別多的時候
     * <p>
     * 之前的方案是每次只運算一位,其實可以每次運算多位,resultArr數組位int型,int表示的范圍為-2^31--2^31-1(-2147483648--2147483647)
     * 可以表示10位之多,所以可以采用位表示9位運算(10位可能越界)
     * 這樣每次運算9位,減少空間消耗,提升計算效率,實際底層也是一位一位運算的,這種提升效率是對于運用層來說的
     */
    public static String optimizeAddStrings(String num1, String num2) {

        int len = (Math.max(num1.length(), num2.length()) + 1) / 9 + 1;

        int[] resultArr = new int[len];

        int carry = 0;

        //9個為一組
        int i = num1.length() - 1, j = num2.length() - 1, index = len - 1;
        while (i >= 0 || j >= 0) {

            if (i < 0) {
                String sN2 = num2.substring(j - 8 > 0 ? j - 8 : 0, j + 1);
                resultArr[index--] = (Integer.parseInt(sN2) + carry) % 1000000000;
                carry = (Integer.parseInt(sN2) + carry) / 1000000000;
                j -= 9;
            } else if (j < 0) {
                String sN1 = num1.substring(i - 8 > 0 ? i - 8 : 0, i + 1);
                resultArr[index--] = (Integer.parseInt(sN1) + carry) % 1000000000;
                carry = (Integer.parseInt(sN1) + carry) / 1000000000;
                i -= 9;
            } else {
                //取9位,不夠則有幾位取幾位
                String sN1 = num1.substring(i - 8 > 0 ? i - 8 : 0, i + 1);
                String sN2 = num2.substring(j - 8 > 0 ? j - 8 : 0, j + 1);
                resultArr[index--] = (Integer.parseInt(sN1) + Integer.parseInt(sN2) + carry) % 1000000000;
                carry = (Integer.parseInt(sN1) + Integer.parseInt(sN2) + carry) / 1000000000;
                i -= 9;
                j -= 9;
            }
        }
        if (index >= 0) {
            resultArr[index--] = carry;
        }

        StringBuilder sb = new StringBuilder(len);
        boolean zeroLeadFlag = true;
        boolean firstNoneZeroFlag = true;
        for (int k = 0; k < len; k++) {
            if (resultArr[k] != 0) {
                zeroLeadFlag = false;
            }
            if (!zeroLeadFlag) {
                //記得補齊9位
                if (firstNoneZeroFlag) {
                    sb.append(resultArr[k]);
                    firstNoneZeroFlag = false;
                } else {
                    String padZeroStr = padZero(String.valueOf(resultArr[k]));
                    sb.append(padZeroStr);
                }
            }
        }
        return zeroLeadFlag ? "0" : sb.toString();
    }

    private static String padZero(String s) {
        StringBuilder sb = new StringBuilder();
        for (int i = s.length(); i < 9; i++) {
            sb.append('0');
        }
        sb.append(s);
        return sb.toString();
    }
}

Review(閱讀一篇英文文章及讀后感)

繼續微服務相關文章, 參考教程用spring boot自己實現一個簡易的微服務
microservices-with-spring-boot

image.png

  • 兩個微服務:CCS(consumer)和FS(provider)
  • Feign用于rest請求
  • Ribbon采用client-side模式負載均衡(在consumer端配置)
  • Eureka Naming Service 用于服務發現(類似于zookeeper)

Tip(一個小技巧)

Logging with Spring Aop(通過Aop攔截器,統一打點方法被調用時的日志)
參考:https://five.agency/logging-with-spring-aop/
雖然一直在使用Spring,但是都是用公司已有框架,正好通過自己編寫一個AOP日志攔截器復習下

Share(心得體會)

share一直不大會寫,分享一下學心理學課看到的一段話:

注意你的思想,因為它將變成言辭;
注意你的言辭,因為它將變成行動;
注意你的行動,因為它將變成習慣;
注意你的習慣,因為它將變成性格;
注意你的性格,因為它將決定你的命運。
早點認識自己,慢慢成為自己,相信我們可以決定自己的命運

所以在平時的生活工作學習中,要完成的事情就立刻去做,不要找借口,行動起來,讓優秀變成一種習慣,讓習慣改善我們的生活,慢慢的改變自己的人生腳本。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,837評論 18 139
  • 下列面試題都是在網上收集的,本人抱著學習的態度找了下參考答案,有不足的地方還請指正,更多精彩內容可以關注我的微信公...
    Java團長閱讀 27,974評論 13 1,115
  • 女人的江山(十) 文| 綠茉兒 自從上次雪兒同萬子墨一塊出去看電影后,萬有才每想起這件事,心里就有說不出的高興,似...
    陜北一姐閱讀 215評論 0 1
  • 就在嵐玉生日前一天中午,他打來電話約她吃飯,他要了菜和米飯。“明天我生日。”她看著他的眼睛說,“正好今天...
    田萍閱讀 242評論 0 2
  • GitHub 在早期沒有專門為組織提供賬號,很多企業用戶或大型開源組織只好使用普通用戶賬號作為組織的共享賬號來使用...
    牛崽兒酷閱讀 126評論 0 0