4.3.2 KMP克努特-莫里斯-普拉特操作

来源:互联网 发布:淘宝没有信誉怎么办 编辑:程序博客网 时间:2024/05/17 04:25

算法需求

  主串S长度n,模式串P长度m,匹配情况是S串的i位置,P串的j位置失配,这个时候为了防止匹配的指针回溯和一些不必要的匹配次数,所以需要查找在S串中“失配”的位置i之前匹配到了P串中j位置k之前的串,这样就可以从k位置开始匹配了,省去了从新匹配的效果

算法推理

  1. 假设此时应与模式中第k(k< j)个位置

  2. 模式中前k-1个字符的字串必须满足下列关系,并且不存在k`>k这种情况
    P1.....Pk1=Sik+1.....Si1

  3. 且已经得到的匹配结果为
    Pjk+1.....Pj1=Sik+1.....Si1
  4. 综合上述的结果可以得到
    P1.....Pk1=Pjk+1.....Pj1
  5. 这个时候求得k值即可知道移动的位置

疑问

可能会疑问,确定移动的j-k个位置,这几个位置没有匹配到的吗,反正法,可以发现如果移动到上次开始的下一个位置,那么可定有k+1在i之前匹配,与之前说的不存在k`这种情况相矛盾所以,成立,现在主要的问题就是怎么去求解这个k值

K值求解

  求解k标记位next[j],next的求职情况

j next[j] 1 0 MAX({k|1 < k < j且P1...Pk1=Pjk+1...Pj1}) 1 2

模式串的的next[j]值,取决于模式串的本身而和相匹配的主串无关,可以从分析其定义出发用递推的方式求的next的函数值
next[1] =0
设next[j]=k,则P1···Pk1=Pjk+1···Pj1,其中1< k < j,且不存在k` > k
那么next[j+1]就得视情况而定
Pk=Pj

P1···Pk=Pjk+1···Pj,由于递推前提是k> k不存在
如果在next[j+1]存在$P_{1}···P_{k+1} = P_{j-k+1}···P_{j+1}$那么必然存在k
> k的值那么递推前提条件不成立

Pk=Pj

这是就相当于P1···Pj为目标字符串,P1···Pk为模式字符串,这个时候问题就相当于重新求P1···Pk字符串的next[k]