KMP算法
KMP算法是一種改進的字符串匹配算法,此算法可以在O(n+m)的時間數量級上完成串的模式匹配操作,基本思想是,每當匹配過程中出現字符串比較不等時,不需回溯指針,而是利用已經得到的“部分匹配”結果將模式向右“滑動”盡可能遠的一段距離,據徐進行比較。
定義:
① 要搜索的關鍵字符串 key K1K2......Km。
② 被搜索的源字符串 source S1S2.....Sn。
u 針對要查找的關鍵字字符串構造失效函數f(s),該函數的功能就是在比較當Ki != Sj的時候計算出從K的第多少個字符開始重新比較。
使得K1K2...Kf(s)是最長的既是K1K2...Ks的的真前綴,又是K1K2...Ks的后綴的字串。也就是說如果我們試圖用一個文本串x匹配K1K2......Km,并且我們已經匹配了前i個字符,但匹配Ki+1的時候失敗,也就是說x的下一個位置不是Ki+1,那么f(s)就是可能和我們當前位置為結尾的文本串匹配的最長的K1K2......Km的前綴和后綴y。也就是說文本x的下一個位置和Kf(s)比較,X當前位置之前的f(s)個字符和K1..Kf(s)是匹配的。所以直接從Kf(s)之后進行比較。
算法如下:
t = 0; f(1) = 0; for (i = 1; i < m; i++) { while(t > 0 && (Ki+1 != Kt+1)) t = f(t); if(Ki+1 == Kt+1) { t = t + 1; f(i+1) = t; } else f(i+1) = 0; } |
對于串"a b a b a a"的計算f(s)的過程如下:
s |
f(s) |
當前字符串 |
說明 |
1 |
0 |
a |
無真前綴 |
2 |
0 |
ab |
無真前綴 |
3 |
1 |
aba |
"a"是"aba"的真前綴和后綴 |
4 |
2 |
abab |
"ab"是"abab"的真前綴和后綴 |
5 |
3 |
ababa |
"aba"是"ababa"的真前綴和后綴 |
6 |
1 |
ababaa |
"a"是"ababaa"的真前綴和后綴 |
u 針檢查S1S2.....Sn是否包含關鍵字K1K2......Km的算法。
s = 0; for (i = 1; i <= n i++) { // 下標從1開始 while (s > 0 && Si != Ks+1) s = f(s); if(Si == Ks+1) s = s + 1; if(s == n) return "yes"; } return "no"; |
</script>