这篇文章写得很好,但是有几点写得不清楚,我在这里补充下http://blog.youkuaiyun.com/A_B_C_ABC/archive/2005/11/25/536925.aspx
其实是一直不理解他那个next函数为什么能跳过。
Next函数的定义如下:
(1)next[0]= -1 意义:任何串的第一个字符的模式值规定为-1。
(2)next[j]= -1 意义:模式串T中下标为j的字符,如果与首字符
相同,且j的前面的1—k个字符与开头的1—k
个字符不等(或者相等但T[k]==T[j])(1≤k<j)。
注:
这里的不等,是任意k个字符都不等。
如:T=”abCabCad” 则 next[6]=-1,因T[3]=T[6]
(3)next[j]=k 意义:模式串T中下标为j的字符,如果j的前面k个
字符与开头的k个字符相等,且T[j] != T[k] (1≤k<j)。
即T[0]T[1]T[2]。。。T[k-1]==
T[j-k]T[j-k+1]T[j-k+2]…T[j-1]
且T[j] != T[k].(1≤k<j);
注:这里的相等的k个字符是1—j-1个匹配中最长的一个,也就是说,任何k个以上个字符时不匹配的,这个很重要,是能跳过的匹配的前提。
(4) next[j]=0 意义:除(1)(2)(3)的其他情况。
其实(3)与(4)可以合二为一,如果把(3)中k的范围化成0≤k<j;这种情况表示其前面0个字符与开头的0个字符相等,且是最大的并且T[k]!=T[j].
这样这个算法就比较容易理解了
下面说说为什么能跳过。
如果next=-1,则任何1- j-1 的都是不匹配的,这样的不匹配,就是我们简单匹配算法中的从1一个一个移动到j-1的不匹配情况的子集,既然子集不匹配,那必然整体就更不匹配了。
如果next=k, 那么表示k—j-1之间的就是不匹配的,这期间的不匹配正好涵盖了我们说的跳过部分的不匹配,所以就能直接跳过。
如此再把结论写出来就不难理解了。
设在字符串S中查找模式串T,若S[m]!=T[n],那么,取T[n]的模式函数值next[n],
1. next[n]= -1 表示S[m]和T[0]间接比较过了,不相等,下一次比较 S[m+1] 和T[0]
2. next[n]=0 表示比较过程中产生了不相等,下一次比较 S[m] 和T[0]。
3. next[n]= k >0 但k<n, 表示,S[m]的前k个字符与T中的开始k个字符已经间接比较相等了,下一次比较S[m]和T[k]相等吗?
4. 其他值,不可能。