KMP匹配算法,
網路上最簡單最易懂的解釋(雖然有錯誤)。
尊重原創...
地址:
http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html
阮一峯老師的kmp算法邏輯有誤,在
中有對該邏輯錯誤的解釋。
該博客並沒有代碼實現,故實現如下:
使用js代碼,按“F12”將代碼扔入控制檯便可運行。
1.獲得next數組
function getNext(s) {
var next = [0];
var p1, p2;
var max = 0;
for (var i = 1; i < s.length; ++i) {
for (var j = 1; j <= i; ++j) {
p1 = s.substr(0, j);
p2 = s.substr(i - j + 1, j);
console.log(i + "::" + p1 + "==" + p2);
if (p1 == p2) {
max = max < p1.length ? p1.length : max;
}
}
next.push(max);
max = 0;
}
return next;
}
運行博客中的測試數據,效果如下:
2.匹配字符串
有了next數組,接下來就是最簡單的樸素模式匹配了,重點在於要根據next數組動態改變i值:
function kmp(s1, s2) {
var next = getNext(s2);
for (var i = 0; i < s1.length;) {
for (var j = 0; j < s2.length; j++) {
if (s1.charAt(i + j) != s2.charAt(j)) {
//重點:i +=(已匹配字符數 - 對應的部分匹配值),樸素模式匹配中,該處總爲 i++;
//注意:在外層for循環中,並沒有i++;
i += j > 0 ? (j - next[j - 1]) : 1;
j = next[j > 0 ? j-1 : 0];
break;
} else if (j == s2.length - 1) {
return i;
}
}
}
return -1;
}
運行結果(忽略next方法的輸出):