转载网络上最简单易懂的KMP模式匹配算法——外加代码实现

来源:互联网 发布:新蓝鸟轮毂数据 编辑:程序博客网 时间:2024/05/22 13:47

 KMP匹配算法,


网路上最简单最易懂的解释(虽然有错误)。


尊重原创...
    地址:
http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html

阮一峰老师的kmp算法逻辑有误,在
http://blog.csdn.net/register_man/article/details/75072797
中有对该逻辑错误的解释。


该博客并没有代码实现,故实现如下:

使用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方法的输出):



原创粉丝点击