KMP模式匹配

记录一下KMP求next和nextval数组的方法

KMP之求next数组

举例:
模式串 a b a a b c a c
next值 0 1 1 2 2 3 1 2

1. next前两位必为0,1。
2. 计算第三位的时候,看第二位b的next值,为1,则把b和1对应的a进行比较,不同,则第三位a的next的值为1,因为一直比到最前一位,都没有发生比较相同的现象。
3. 计算第四位的时候,看第三位a的next值,为1,则把a和1对应的a进行比较,相同,则第四位a的next的值为第三位a的next值加上1,为2。因为是在第三位实现了其next值对应的值与第三位的值相同。
4. 计算第五位的时候,看第四位a的next值,为2,则把a和2对应的b进行比较,不同,则再将b对应的next值1对应的a与第四位的a进行比较,相同,则第五位的next值为第二位b的next值加上1,为2。因为是在第二位实现了其next值对应的值与第四位的值相同。
5. 计算第六位的时候,看第五位b的next值,为2,则把b和2对应的b进行比较,相同,则第六位c的next值为第五位b的next值加上1,为3,因为是在第五位实现了其next值对应的值与第五位相
6. 计算第七位的时候,看第六位c的next值,为3,则把c和3对应的a进行比较,不同,则再把第3位a的next值1对应的a与第六位c比较,仍然不同,则第七位的next值为1。
7. 计算第八位的时候,看第七位a的next值,为1,则把a和1对应的a进行比较,相同,则第八位c的next值为第七位a的next值加上1,为2,因为是在第七位和实现了其next值对应的值与第七位相同。

总结:求解next时前两位为0,1。之后的next计算要根据前一位的字符与其next值所对应的字符比较,相同则按此规则继续向前比较直至不同,取不同的那一项的next值。

改进的KMP之求解nextval

求nextval数组值有两种方法,一种是不依赖next数组值直接用观察法求得,一种方法是根据next数组值进行推理,两种方法均可使用,视更喜欢哪种方法而定。本文主要分析nextval数组值的第二种方法。

例子:

 模式串 a b a a b c a c
 next值 0 1 1 2 2 3 1 2
 nextval值 0 1 0 2 1 3 0 2

  1. 第一位的nextval值必定为0,第二位如果与第一位相同则为0,如果不同则为1。
  2. 第三位的next值为1,那么将第三位和第一位进行比较,均为a,相同,则第三位的nextval值为0。
  3. 第四位的next值为2,那么将第四位和第二位进行比较,不同,则第四位的nextval值为其next值,为2。
  4. 第五位的next值为2,那么将第五位和第二位进行比较,相同,第二位的next值为1,则继续将第二位与第一位进行比较,不同,则第五位的nextval值为第二位的next值,为1。
  5. 第六位的next值为3,那么将第六位和第三位进行比较,不同,则第六位的nextval值为其next值,为3。
  6. 第七位的next值为1,那么将第七位和第一位进行比较,相同,则第七位的nextval值为0。
  7. 第八位的next值为2,那么将第八位和第二位进行比较,不同,则第八位的nextval值为其next值,为2。

总结:求解nextval时,第一位是0;模式串第二位若与第一位相同则nextval第二位取0,否则取1。对于此后的nextval[i],将字符串的第i位与第next[i]位比较,如果相同,则继续按照这种方法向前比较直至不同,然后取不同的那个next值,如果一直比较到第一位无论相同与否都取0。