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中的出現次數。