KMP字符串匹配算法的僞代碼

KMP算法的圖解:http://blog.csdn.net/u010232171/article/details/41945605

圖解中的減法操作與下面的僞代碼不同,應該以下面的代碼爲準


KMP算法的next數組求解:http://blog.csdn.net/u010232171/article/details/41961837



下面的僞代碼出自《算法引論—— 一種創造性方法》,作者Udi Manber,第六章的6.7小節(多讀書真的可以擴寬知識面,好的解或許就在其中)


算法 String_Match(A, n, B, m)

輸入:A(長度爲n的字符串)和B(長度爲m的字符串), A是原串,B是模式串

輸出:Start(B在A中第一次出現的下標,即使得B是A中從A[start]開始的子串的第一個下標)

注意:數組的下標從1開始


時間複雜度O(n)

Begin

     i = 1, j =1,  start = 0;

     while  start == 0 and i <= n do

           if B[j] == A[i] then

                 j = j + 1;

                 i = i + 1;

           else

                j = next[j] + 1;

               if j == 0 then

                   j = 1;

                   i = i + 1;

               end if;

           end if;

           if j == m + 1 then

              start = i - m;

           end if;

     end while;

End;


----------------------------------------------------------------------------------------------------------------------------------------------------------

KMP算法中的next數組從下面的程序中得到。。。。。


算法 Compute_Next(B, m)

輸入:B(長度爲m的字符串)

輸出:next(大小爲m的數組)

注意:B和next的下標都是從1開始

next數組的意義:next[i] = max( j | B(1 to j) == B(i-j, to i-1), 0 < j < i-1 ),即B與A在i處出現字符不相等時,B向右移動的最大距離。


時間複雜度:O(m)

Begin

     next[1] = -1;

     next[2] = 0;

     for i = 3 to m do

           j = next[i-1] + 1;

           while B[i-1] != B[j] and j > 0 do

                 j = next[j] + 1;

           end while;

           next[i] = j;

      end for;

End;



核心思想就是B與A在i處發生不匹配時,那麼應該向右移動B。最笨的方法是每次都只移動一位,然後重頭開始比較,那麼時間複雜度爲O(m*n)。KMP算法利用已經匹配部分字符串(B(1 to i-1))的特點,選擇儘量大且不漏掉可能匹配的移動距離. 也就是B(1 to i -1)的前綴和後綴的最大相等值。


在hihocoder題庫中一道非常標準的KMP題目(已解決),它求的是B在A中的出現次數。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章