• KMP算法之Next数组详解


    最近刚好学到了kmp算法,对我来说还蛮难的,原理还好理解,就是next数组的求解让我很懵

    旁听了一下隔壁班大佬的分享,觉得他们讲得特别好,就想来记录一下

    最长公共前后缀

    kmp算法首先要找“最长公共前后缀”,其定义为:A的“最长公共前后缀”是“A中以最后一个字符结尾的非前缀子串”与“A的前缀”能够匹配的最大长度。
    例:ababab
    我们从“最大长度”6开始向下枚举
    若答案是6。根据定义,“A中以最后一个字符结尾的非前缀子串”是ababab?我们注意到,ababab也算它自身的一个前缀
    因此,在枚举时,要从这个字符串的长度减一开始枚举!


    若答案是5,则“非前缀子串”为babab。而“前缀”是ababa。两者不相等。


    若答案是4,则“非前缀子串”为abab,而“前缀”是abab。两者相等。
    所以我们可以确定,字符串”ababab”的“最长公共前后缀”长度为4。

    有什么用?

    举例说明:有两个字符串

    S: abaacababcac
    T: ababc
    首先,根据最长公共前后缀,我们写出T串的所有前缀的“最长公共前后缀”长度:
    T[0~0] = “a”,最长公共前后缀长度:0
    T[0~1] = “ab”,最长公共前后缀长度:0
    T[0~2] = “aba”,最长公共前后缀长度:1
    T[0~3] = “abab”,最长公共前后缀长度:2
    T[0~4] = “ababc”,最长公共前后缀长度:0
    我们把求得的这5个数记为X数组(因为它还不是next数组)

    这个更改后的X数组就是next数组,下图是上面的执行

    next数组的含义是:当S[i]和T[j]不相等,并且j不等于-1时,j指针该指向的位置,且i指针不动。

    当然我们目前只是枚举,接下来如何用算法实现求next数组

    求next数组

    假设一个新的字符串
    R:       a b c a b d e a b c a b c f
    next:  -1 0 0 0 1 ?
    我们要求next[5]

    情况一 R[i-1] == R[next[i-1]]

    比如R[5-1]=R[1],所以显然next[6]=next[5]+1=2

     情况二 若R[i-1]!=R[next[i-1]]

    R:       a b c a b d e a b c a b c f
    next: -1 0 0 0 1 2 ?
    我们发现R[i-1]和R[next[i-1]]并不相等。

    用肉眼可以看出,我们在abcabd不管怎么取后缀,后缀的最后一个字符d,从来就没有在前面出现过。所以它不可能和任何一个前缀相等。所以next[6]才是0。


    假设我们求到了这种程度
    R:       a b c a b d e a b c a b c f
    next:  -1 0 0 0 1 2 0 0 1 2 3 4 5 ?
    发现R[2] == ‘c’。换言之,枚举next[13]时,我们发现6不行,5不行,4不行,其原因都在最后一个字符’c’不是前缀的最后一个字母。
    刚才我们发现R[next[12]],也就是R[5],和这个最后一个字符是不一样的
    但是,R[next[5]] = R[2] = ‘c’就和R[12]是一样的。也就是说,R[12] == R[next[next[12]]]。
    这不是巧合。可以证明,只要找到了这个’c’,且next[next[12]]=2,则R[13]就是2+1=3。并且可以证明,除了next[12]+1,next[next[12]]+1,next[next[next[12]]]+1…以外,next[13]不会有其他的答案了。
    只要多次迭代,就能求出next[13]。
    经过多次迭代,如果发现迭代到了-1这里还没有找到最后一个字符,那么我们直接让next[13]=-1+1=0就可以了。这也是我们让那个X[0]=-1的又一个原因。

    总结

     这就是求整个next数组的详细过程了,匹配的过程大家应该都懂,就不说了。

  • 相关阅读:
    androd Eclipse Ant 批量打包
    Eclipse中不显示Ant,如何操作
    android Eclipse 多渠道打包
    Android 关于tools
    (转)android studio 使用的主要操作
    Android的NDK开发步骤
    AnimatorSet中before与after的理解
    (转)Android webview 调用相机和照片库 实现文件的上传
    混淆的小记录
    Xamarin.Forms on WPF (Win7)
  • 原文地址:https://www.cnblogs.com/zlszls3113373723/p/12785676.html
Copyright © 2020-2023  润新知