• KMP求最小循环节讲解


    KMP最小循环节、循环周期:

    定理:假设S的长度为len,则S存在最小循环节,循环节的长度L为len-next[len],子串为S[0…len-next[len]-1]。

    (1)如果len可以被len - next[len]整除,则表明字符串S可以完全由循环节循环组成,循环周期T=len/L。

    (2)如果不能,说明还需要再添加几个字母才能补全。需要补的个数是循环个数L-len%L=L-(len-L)%L=L-next[len]%L,L=len-next[len]。

    理解该定理,首先要理解next数组的含义:next[i]表示前面长度为i的子串中,前缀和后缀相等的最大长度。

    如:abcdabc

    index

    0

    1

    2

    3

    4

    5

    6

    7

    char

    a

    b

    c

    d

    a

    b

    C

    next

    -1

    0

    0

    0

    0

    1

    2

    3

    如对于a,ab,abc,abcd,很明显,前缀和后缀相同的长度为0

      对于长度为5的子串abcda,前缀的a和后缀的a相同,长度为1

      对于长度为6的子串abcdab,前缀的ab和后缀的ab相同,长度为2

    接下来举几个例子来说明最小循环节和循环周期:

    为方便说明,先设字符串的长度为len,循环子串的长度为L

    1.

    s0s1s2s3s4s5 ,next[6]=3

    即s0s1s2=s3s4s5

    很明显可知:循环子串为s0s1s2,L=len-next[6]=3,且能被len整除。

    2.

    s0s1s2s3s4s5s6s7 ,next[8]=6

    此时len-next[8]=2 ,即L=2

    由s0s1s2s3s4s5=s2s3s4s5s6s7

    可知s0s1=s2s3,s2s3=s4s5,s4s5=s6s7

    显然s0s1为循环子串

    3.

    s0s1s2s3s4s5s6 ,next[7]=4

    此时len-next[7]=3,即L=3

    由s0s1s2s3=s3s4s5s6

    可知s0s1=s3s4,s2s3=s5s6

    从而可知s0s1s2=s3s4s5,s0=s3=s6

    即如果再添加3-4%3=2个字母(s1s2),那么得到的字符串就可以由s0s1s2循环3次组成

    这个定理可以这么理解:

    http://www.cnblogs.com/oyking/p/3536817.html

    对于一个字符串,如abcd abcd abcd,由长度为4的字符串abcd重复3次得到,那么必然有原字符串的前八位等于后八位。

    也就是说,对于某个字符串S,长度为len,由长度为L的字符串s重复R次得到,当R≥2时必然有S[0..len-L-1]=S[L..len-1],字符串下标从0开始

    那么对于KMP算法来说,就有next[len]=len-L。此时L肯定已经是最小的了(因为next的值是前缀和后缀相等的最大长度,即len-L是最大的,那么在len已经确定的情况下,L是最小的)。

    如果一定仔细证明的话,请看下面:

    (参考来自:http://www.cnblogs.com/wuyiqi/archive/2012/01/06/2314078.html,有所改动)

     k    m   x     j     i

    由上,next【i】=j,两段红色的字符串相等(两个字符串完全相等),s[k....j]==s[m....i]

    设s[x...j]=s[j....i](xj=ji)

    则可得,以下简写字符串表达方式

    kj=kx+xj;

    mi=mj+ji;

    因为xj=ji,所以kx=mj,如下图所示

     k   m     a    x    j     i

    设s[a…x]=s[x..j](ax=xj)

    又由xj=ji,可知ax=xj=ji

    即s[a…i]是由s[a…x]循环3次得来的。

    而且看到没,此时又重复上述的模型,s[k…x]=s[m…j],可以一直递推下去

    最后可以就可以递推出文章开头所说的定理了。

    最后再举两个相关例子

    abdabdab  len:8 next[8]:5

    最小循环节长度:3(即abd)   需要补的个数是1  d

    ababa  len:5 next[5]:3

    最小循环节长度:2(即ab)    需要补的个数是1  b

    --------------------- 本文来自 hao_zong_yin 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/hao_zong_yin/article/details/77455285?utm_source=copy

  • 相关阅读:
    关于jQuery的选择器
    解读position定位
    html5新增的功能。
    关于ajax的同步异步
    响应式布局由来和剖析
    jQuery的效果函数及如何运用
    jQuery的选择器
    position定位的解析与理解
    HTML5与CSS3中新增的属性详解
    对Ajax的解析
  • 原文地址:https://www.cnblogs.com/Kissheart/p/9744345.html
Copyright © 2020-2023  润新知