KMP算法计算next函数值及函数修正值(nextval)
给出一条字符串有n个字符,除掉最后一个字符,前面的按顺序可得到含有1,2,3……n-2,n-1个字符的子串称为该字符串的前缀串;相应地,除掉最前面一个字符,得到含有n-1,n-2,……2,1个字符的子串称为该子符串的后缀串。
在求next函数值与nextval值时,我们要得出前缀串和后缀串的最长相同串:
例:aba
该字符串的前缀串有:ab,a;后缀串有:ba,a;
可知前缀串和后缀串相同为a,字符个数为1;
ababab
该最长相同串为含有4个字符的子串;
现在根据上面的来求next值:
给出一条字符串,a b a b a a a b a b a a
先分别在每一个字符下面写出该字符之前构成的字符串的最长相同串,可得0 0 1 2 3 1 1 2 3 4 5 6①
这里有个技巧,
当到第3个字符时,其下标可得出为1,
第4个字符时,因为第3个已对比与第1个字符相同,故第4个字符可直接与第2个字符比较,若相同,得出2,接下去若第5个与第3个字符相同,则第5个字符下表为3,继续下去也是一样;
若第4个字符与第2个字符不同,则第4个字符就得重新回到与第1个字符比较;类似地,若是在第4个字符与第2个字符相同的前提下,对比第5个与第3个,如若不同,仍需把第5个字符回到与第1个字符比较。
完成后,就得出一组数值0 0 1 2 3 1 1 2 3 4 5 6①,后将该数组删去最后一位,再各个数字加1,得到
1 1 2 3 4 2 2 3 4 5 6②,再在1 1 2 3 4 2 2 3 4 5 6②数组最前面补0作开头,得到0 1 1 2 3 4 2 2 3 4 5 6③,这就是该字符串的next数组。
再求该字符串的nextval:
前面求next得出两组数组:
0 0 1 2 3 1 1 2 3 4 5 6①
0 1 1 2 3 4 2 2 3 4 5 6③
将这两组数组各个数值逐一相对比,
若③中与①中有不同的,就先抄下来,得到* 1 * * * 4 2 * * * * * ④,
再在③数组其余数值中,看到第一个数值为0,可理解为第0个数值,理所当然,第0个不存在,故在④中第1个填0;③中第3个数值为1,即找出④中第1个数值,填进④中第3个中,以此类推,③中第4个为2,找出④中第2个数值,将值填进④中第4个中,
这样,就得出完整的数组④:0 1 0 1 0 4 2 1 0 1 0 4
数组④即为该字符串的nextval值。