KMP算法心得

在介紹kmp算法之前仔掸,我想先簡單介紹一下Brute-Force算法憔儿,這是一個回溯的字符串模式匹配算法赠堵,是一個簡單暴力狂!

1-1. Brute-Force算法分析

由上圖的匹配思想法褥,主要代碼如下:

public static int indexOf(String target, String pattern){
    
    int i = 0,j = 0;

    while(i < target.length() - pattern.length()){
        
        if(target.charAt(i+j) == pattern.charAt(j)){
            j++;
        }else{
            i++;
            j = 0;
        }
        if(j == pattern.length()){
            return i;
        }
    }
    return -1;
}

很明顯茫叭,當(dāng)匹配不成功時,目標串每次向前移動一位半等,模式串每次從P0開始重新匹配揍愁,雙方都存在回溯現(xiàn)象。在上圖中可以看出最差的情況: 每次匹配比較M次杀饵,比較了N - M + 1 次莽囤,比較總數(shù)是 M*(N - M + 1),由于M << N切距,所以時間復(fù)雜度O(M * N) 朽缎。

下面分析下Brute-Force算法的缺點:

1-2. Brute-Force算法缺點

下面就著重講一下KMP算法:

  1. 算法描述:

    核心是找到模式串中的k( 0 <=k < j) 滿足"P0...Pk-1" = "Pj-k...Pj-1" = "Ti-k...Ti-1"  (當(dāng)Pj != Ti時)庆杜,則模式串從Pk開始遍歷薄翅。
    

所以問題就轉(zhuǎn)化為:找到串"P0...Pj-1"相同的前綴子串和后綴子串的長度k。

1-3. KMP算法描述
  1. 求next數(shù)組
1-4. next公式

根據(jù)上圖的模式串"abcabc"蜡峰,可以得到next數(shù)組(注意在"P0...Pj-1"中尋找)

j 0 1 2 3 4 5
模式串 a b c a b c
next[j] -1 0 0 0 1 2
  1. 計算next數(shù)組的算法

由next數(shù)組的定義可以:

    1. next[0] = -1;
  • 2.對于任意的j (0<=j <m ) next[j] < j;
    1. 若next[j] = k 說明在子串"P0...Pj-1"中存在相同的前綴子串和后綴子串葡幸,"P0...Pk-1" = "Pj-k...Pj-1" (0=<k<j最筒,k取最大值);
    1. 對于next[j+1]而言蔚叨,判斷"P0...Pj"子串中床蜘,是否存在"P0...Pk" = "Pj-k...Pj-1Pj"的問題辙培,可以分解為 :
        1. 是否存在"P0...Pk-1" = "Pj-k...Pj-1"的問題;
        1. Pk == Pj的問題邢锯;

很符合動態(tài)規(guī)劃(Dynamic Programming)的問題扬蕊,把多階段過程轉(zhuǎn)化為一系列單階段問題,利用各階段之間的關(guān)系弹囚,逐個求解厨相,很像分治法。
同時個人認為很像高考數(shù)列的相關(guān)問題 ---- 數(shù)學(xué)歸納法鸥鹉。

某個數(shù)列 An

  1. An = K (常數(shù))蛮穿;
  2. 假設(shè)前N項滿足: An = f(n) (某個函數(shù)式);
  3. 如果第N+1項 滿足 An+1 = f(n+1)毁渗,則An = f(n) 等式成立践磅。

綜上所述該動態(tài)規(guī)劃的遞推公式:

D(j+1) = max(D(j)) + (Pk == Pj ? 1 : 0)

  1. 改進next數(shù)組

在上圖1-3中 Pk = Pj , Ti != Pj => Pk != Ti 則完全沒有必要回溯到Pk開始比較,直接從P0開始灸异,所以假如next[j] = k 且 Pk = Pj 則 next[j] = next[k];

  1. KMP核心代碼
private static int[] getNext(String pattern){

        int j = 0,k = -1;
        int[] next = new int[pattern.length()];
        next[0] = -1;
        while(j < pattern.length() - 1){
            if(k == -1 || pattern.charAt(j) == pattern.charAt(k)){
                j++;
                k++;
                //改進next數(shù)組
                if(pattern.charAt(j) != pattern.charAt(k)){
                    next[j] = k;
                }else{
                    next[j] = next[k];
                }
            }else{
                k = next[k];
            }
        }
        return next;
    }
    public static int indexOf(String target, String pattern){
        
        int i = 0,j = 0;
        
        int[] next = getNext(pattern);
        
        while(i < target.length()){
            
            if(j == -1 || target.charAt(i) == pattern.charAt(j)){
                
                i++;
                j++;
            }else{
                j = next[j];
            }
            if(j == pattern.length()){
                
                return i - j;
            }
        }
        return -1;
    }
  1. KMP算法分析
1-5. KMP算法分析

時間復(fù)雜度O(M + N) 府适,當(dāng)M<<N或者比較次數(shù)少(匹配的成功率比較高),時間復(fù)雜度O(N)肺樟。

以上是本人對KMP算法的理解檐春,歡迎大家指正和交流,謝謝么伯!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末疟暖,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子田柔,更是在濱河造成了極大的恐慌俐巴,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件硬爆,死亡現(xiàn)場離奇詭異欣舵,居然都是意外死亡,警方通過查閱死者的電腦和手機缀磕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門缘圈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人袜蚕,你說我怎么就攤上這事准验。” “怎么了廷没?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵糊饱,是天一觀的道長。 經(jīng)常有香客問我颠黎,道長另锋,這世上最難降的妖魔是什么滞项? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮夭坪,結(jié)果婚禮上文判,老公的妹妹穿的比我還像新娘。我一直安慰自己室梅,他們只是感情好戏仓,可當(dāng)我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著亡鼠,像睡著了一般赏殃。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上间涵,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天仁热,我揣著相機與錄音,去河邊找鬼勾哩。 笑死抗蠢,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的思劳。 我是一名探鬼主播迅矛,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼潜叛!你這毒婦竟也來了诬乞?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤钠导,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后森瘪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體牡属,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年扼睬,在試婚紗的時候發(fā)現(xiàn)自己被綠了逮栅。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡窗宇,死狀恐怖措伐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情军俊,我是刑警寧澤侥加,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站粪躬,受9級特大地震影響担败,放射性物質(zhì)發(fā)生泄漏昔穴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一提前、第九天 我趴在偏房一處隱蔽的房頂上張望吗货。 院中可真熱鬧,春花似錦狈网、人聲如沸宙搬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽勇垛。三九已至,卻和暖如春拓售,著一層夾襖步出監(jiān)牢的瞬間窥摄,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工础淤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留崭放,地道東北人。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓鸽凶,卻偏偏與公主長得像币砂,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子玻侥,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容