KMP算法next数组

private static int[] next(String p) {
        int[] next = new int[p.length()];
        next[0] = -1;
        int k = -1, j = 2;
        while (j < p.length() - 1) {
            if (k == -1 || p.charAt(k) == p.charAt(j)) {
                k++;
                j++;
                next[j] = k;
            } else {
                k = next[k];
            }
        }
        return next;
    }

上面是next数组的基本代码。
next[j]表示以j坐标的前一位结尾的最大公共前后缀的长度。
按照数组的表示我们知道从开头j长度为j+1。那么上面这个next[j]还可以解释为:
next[j]表示以j坐标的前一位结尾的最大公共前缀的后一位。
举个例子:
“abcabds”
d所在的索引是5,next[5]=2。是以b结尾的最大前缀的后一位,即c的索引。
明白了这一点,当p.charAt(k) != p.charAt(j)的时候,k = next[k]就会很好理解。
首先朴素的想法是k直接回退就是k=k-1,这种效率不高。
我们假设匹配的前缀为…ad,匹配的后缀为…ae
此时要在前缀找…ae怎么找,直接找e会很麻烦,我们可以找它的前一位,它的前一位必是匹配的。而由上面的分析可知,next正好存的是匹配前缀的后一位。这样就是找最长的前缀
…a的后一位的坐标,然后检测它是否与e相等就好了。
例子:
abeabz…abeabr
当检测到z!=r时,
我们要在abeabz,找…br,相当于找b?这样的串的子集,而这样的串都是以next[k]为索引结尾的,而next[k]的坐标正好是?的坐标。这样就会比k=k-1快的多。
还有一个问题:
abreabz…abeabr
这样当k=2的时候为什么前面的ab必定是匹配的?
很简单,因为next表示的就是存的就是公共前后缀里面前缀的后一位。
因为abreab是前后公共前后缀。而ab又是前缀部分的公共前后缀。
后一个是前一个的子集合。
我只能说设计这个算法的人是个大神。
同时想说csdn真是不的了,kmp那么多文章,互相来回抄,没有一篇让我看懂,可能我是个弱智。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值