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

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值