KMP 算法要解決的是在字符串 S 中尋找模式字符串 P 的問題。
naive 的方法是兩重循環,時間復雜度 O(m*n)。KMP 的時間復雜度為 O(m+n)。
其實并不復雜,分兩步:
- 求出 P 的 Partial Match Table
- 借助 table 搜索 S
時間復雜度 O(m+n)。關鍵步驟是求出 P 的 Partial Match Table,其含義是
The length of the longest proper prefix in the (sub)pattern that matches a proper suffix in the same (sub)pattern
其中,
Proper prefix: All the characters in a string, with one or more cut off the end. “S”, “Sn”, “Sna”, and “Snap” are all the proper prefixes of “Snape”
Proper suffix: All the characters in a string, with one or more cut off the beginning. “agrid”, “grid”, “rid”, “id”, and “d” are all proper suffixes of “Hagrid”
實現如下
public int[] kmpTable(String p) {
// 一開始是聲明 p.length() 長度的數組來表示相應位的狀態,但是 table[1] = 1 時會一直循環
int[] table = new int[p.length()+1];
int i = 2, cnt = 0;
while (i <= p.length()) {
if (p.charAt(i - 1) == p.charAt(cnt)) {
table[i++] = ++cnt;
} else if (cnt > 0) {
cnt = table[cnt];
} else {
table[i++] = 0;
}
}
return table;
}
參考文獻