1. 程式人生 > 其它 >資料結構與演算法學習(二)-字串相關問題

資料結構與演算法學習(二)-字串相關問題

技術標籤:java

我的個人部落格Alexios,歡迎大家來吐槽交流。

1、String、StringBuffer與StringBuilder的區別

1.1、String類

分析原始碼可知,String物件的內容是儲存在一個char陣列中,且這個陣列使用final修飾,這也是String物件不可變的原因。當進行字串拼接時,虛擬機器會新建一個字串物件,然後將新的字串物件賦值給原來的引用,而不是真的修改了原來字串物件的值。

字串重寫了Object父類的equals方法。

1.2、StringBuffer類和StringBuilder類

這兩個類均繼承於AbstractStringBuilder類,但分析原始碼可知StringBuffer的方法都添加了synchronized關鍵詞進行修飾,所以StringBuffer是執行緒安全的,而沒有使用synchronized修飾方法的StringBuilder是執行緒不安全的,但StringBuilder的速度要遠遠高於StringBuffer,所以在能保證執行緒安全的情況下,StringBuilder的優先順序要高於StringBuffer。

1.3、總結

  • String是一個final修飾的類,所有的屬性也是final的,所以String具有不可變性,也就是對字串的操作,如拼接、剪下都會產生新的String物件。
  • StringBuffer本質是一個執行緒安全的可修改字串序列。因為保證執行緒安全,所以會帶來額外的效能消耗。
  • StringBuilder本質上和StringBuffer沒有區別,但是StringBuilder去掉了執行緒安全部分提高了操作效率,是絕大部分情況下字串拼接的首選。
  • 如果確定拼接字串會發生多次,並且長度可預計,那麼可以在開始的時候指定合適的大小,避免陣列擴容造成的開銷。

2、找出字串中出現最多次的字元和出現的次數

遍歷字串,並使用一個HashMap來儲存出現字元及出現的次數,以字元為key,次數為value。解題思路如下

  • 假定字串中出現最多的字元maxCode為當前字串的第一個元素,出現次數maxCount初始化為0

  • 遍歷字串,判斷當前字元是否在hashmap的key中,如果包含,令次數+1,否則將該字元為key,1為value放入hashmap中

  • 判斷maxCount和當前字元出現次數的關係,如果maxCount小於當前字元出現次數,就令maxCode = 當前字元,然後更新maxCode,最後返回maxCode和maxCount即可。

程式碼實現

    /***
     * 找出字串中出現最多次的字元和出現的次數
     * @param str 目標字串
     * @return 以maxCode為鍵、maxCount為值的map
     */
public static Map<Character, Integer> findMostCodeAndCount(String str) { char maxCode = str.charAt(0); int maxCount = 0; Map<Character, Integer> map = new HashMap<>(); for (int i = 0; i < str.length(); i++) { Character currentCode = str.charAt(i); Integer count = map.get(currentCode); if(count == null) { count = 1; } else { count++; } map.put(currentCode, count); if(maxCount < count) { maxCode = currentCode; maxCount = count; } } Map<Character, Integer> result = new HashMap<>(); result.put(maxCode,maxCount); return result; }

測試程式碼及結果

        String str = "abcacba";
        Map result = findMostCodeAndCount(str);
        System.out.println(result);
  • 結果

image-20210129152842664

3、找出字串中第一次重複出現的字元

使用一個HashSet來解決問題,由於Set有不允許元素重複的性質,Set的add方法在新增重複值是會返回false,所以我們可以用這個性質來判斷元素是否重複。

程式碼實現

    /***
     * 找出字串中第一次重複出現的字元
     * @param str 目標字串
     * @return 返回第一次重複的字元
     */
    public static Character getFirstRepeat(String str) {
        Set<Character> set = new HashSet<>();
        Character result = null;
        for (int i = 0; i < str.length(); i++) {
            Character currentCode = str.charAt(i);
            if(!set.add(currentCode)) {
                result = currentCode;
                break;
            }
        }
        return result;
    }

測試程式碼和結果

        String str = "abcacba";
        Character result = getFirstRepeat(str);
        System.out.println(result);
  • 結果

image-20210129152855053

4、兩個大數之和

題目描述:現在有兩個數,位數均超過1000位,例如

  • String a = “123343432…”

  • String b = “3974928374928…”

這兩個大數無法轉換為Integer計算,所以我們使用兩個陣列來儲存這兩個數,然後進行計算。

解題思路如下

  • 設這兩個數中大的數的位數位m,則結果的最大位數位m+1
  • 用一個int陣列來儲存結果

程式碼實現

    /***
     * 程式設計兩個大數之和
     * @param num1
     * @param num2
     * @return
     */
    public static String sumOfBigNum(String num1,String num2) {
        char[] largeArray = null;
        char[] smallArray = null;
        if(num1.length() >= num2.length()) {
            largeArray = num1.toCharArray();
            smallArray = num2.toCharArray();
        } else {
            largeArray = num2.toCharArray();
            smallArray = num1.toCharArray();
        }
        int[] res = new int[largeArray.length + 1];
        for (int i = 0; i < largeArray.length; i++) {
            res[i] = largeArray[largeArray.length - i - 1] - '0';
        }
        for (int i = 0; i < smallArray.length; i++) {
            res[i] += smallArray[smallArray.length - i - 1] - '0';
        }
        for (int i = 0; i < res.length - 1; i++) {
            if(res[i] > 9) {
                res[i + 1] += res[i] / 10;
                res[i] %= 10;
            }
        }
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = res.length - 1; i >= 0; i--) {
            stringBuilder.append(res[i]);
        }

        String result = stringBuilder.toString();
        if(result.startsWith("0")) {
            result = result.substring(1);
        }
        return result;
    }

測試程式碼和結果

        String num1 = "12345";
        String num2 = "56756";
        Integer n1 = Integer.valueOf(num1);
        Integer n2 = Integer.valueOf(num2);
        Integer sum = n1 + n2;
        System.out.println("計算機計算結果為:" + sum);
        System.out.println("函式計算結果位:" + sumOfBigNum(num1,num2));
  • 結果

image-20210129152910086