面試題精選:字符串替換

字符串處理在程序猿平常工做工做中很是常見,常見到幾乎各類語言中都已經封裝好了字符串相關的API,咱們只須要直接拿過來用就好。就拿Java爲例,jdk中的String()類幾乎封裝了全部字符串相關的操做,其方法數量有近百個,幾乎知足了程序猿全部字符串相關的操做。
在這裏插入圖片描述
正是由於這麼方便,估計大多數Java程序猿都沒本身實現過字符串的replace。這裏正式引入一下今天的精選面試題:不依賴第三方庫 實現一個字符串替換replace(String str, String target, String replacement)函數,其功能是將str中全部的target替換爲replacement。 其實這道題並不涉及任何複雜或者高深的算法,只須要掌握基本的編程就能夠作,但當我某次把這道題拿出來面試某個應屆生時,他代碼寫的磕磕絆絆的,後來我也陸陸續續用這題考過好幾我的,鮮有順暢寫出來的,是我低估了這道題的難度??
在這裏插入圖片描述html

解題思路

回到題目自己,我多說兩句,仔細想一想這道題其實也很簡單,然而這就難倒了一大批人,你們刷面試題前仍是要先打好編程基礎。 這題的解題思路也很簡單,咱們新建個StringBuilder,只須要把str中不是target的部分加進去,若是是遇到target,就把replacement字符串加進去,真的沒有任何複雜的算法 就是單純考你編程的基本功,代碼以下。java

public static String replace(String str, String target, String replacement) {
        // 正常這裏須要對str,target,replacement作輸入校驗,這裏我省略, 好比str比target端的時候能夠直接返回空字符串  
        StringBuilder res = new StringBuilder();
        for (int i = 0; i < str.length(); ) {
            if (isMatch(str, i, target)) {
                i += target.length();  // 若是匹配,須要直接向前跳target.length  
                res.append(replacement);
                continue;
            }
            res.append(str.charAt(i++));
        }
        return res.toString();
    }

    // 單純確認從str的pos位置開始,是否和target相匹配  
    private static boolean isMatch(String str, int pos, String target) {
        for (int i = 0; i < target.length() && i + pos < str.length(); i++) {
            if (str.charAt(i + pos) != target.charAt(i)) {
                return false;
            }
        }
        return true;
    }

看吧,代碼其實沒啥難度,但咋就好多明顯刷過其餘面試題的人都不會呢!!!面試

Jdk中的replace實現

估計大多數人都沒看過Jdk中的實現,因此順帶咱們來欣賞下java String類中的replace方法是如何實現的。算法

public String replace(CharSequence target, CharSequence replacement) {
        String tgtStr = target.toString();
        String replStr = replacement.toString();
        int j = indexOf(tgtStr);
        if (j < 0) {
            return this;
        }
        int tgtLen = tgtStr.length();
        int tgtLen1 = Math.max(tgtLen, 1);
        int thisLen = length();

        int newLenHint = thisLen - tgtLen + replStr.length();
        if (newLenHint < 0) {
            throw new OutOfMemoryError();
        }
        StringBuilder sb = new StringBuilder(newLenHint);
        int i = 0;
        do {
            sb.append(this, i, j).append(replStr);   // 先把未匹配字符添加進去,而後直接添加replStr  
            i = j + tgtLen;
        } while (j < thisLen && (j = indexOf(tgtStr, j + tgtLen1)) > 0);  // 找到下一個匹配的下標 
        return sb.append(this, i, thisLen).toString();
    }

jdk中的思路和咱們上面寫的思路是一致的,但jdk的代碼更爲精簡,其實jdk也沒用啥高深的東西,只是在indexOf()中考慮了更多數據編碼的問題。編程

題目擴展

別看這道題簡單,其實它也有好多能夠擴展的地方,我來隨便擴幾個供你們參考下。app

  1. Java中字符處理確定免不了String StringBuffer和StringBuilder,都有啥區別?
  2. 以前老程序猿不推薦使用 str = str + "xx"的方式拼接字符串, 爲何? 而如今其實大多數狀況下用StringBuilder.append和+拼接字符串就沒那麼多差別了? (提示:高版本的java對+的字符串拼接方式有優化)!
  3. 上文中咱們用到了字符串匹配的方式,咱們用的是最普通的匹配時間複雜度最差是O(mn),使用其餘的匹配算法能夠大幅提高性能,你都知道有哪些字符串匹配算法?(好比你們最耳熟能詳的就是KMP)

歡迎關注個人面試專欄面試題精選永久免費 持續更新,本專欄會收集我遇到的比較經典面試題,除了提供詳盡的解法外還會從面試官的角度提供擴展題,但願能幫助你們找到更好的工做。另外,也徵集面試題,若是你遇到了不會的題 私信告訴我,有價值的題我會給你出一篇博客。
本文來自https://blog.csdn.net/xindoo函數

相關文章
相關標籤/搜索