以前一直没搞懂kmp算法,可能没用心去理解,最近茅厕顿开,搞明白了。
kmp短小精妙,能将串比较减少到O(m+n)的复杂度,比一般的O(m*n)要强得多。
要想理解kmp,得先了解next数组的奥妙。
先引用网上一段解释:
next数组存储的是一个失败函数,也就是自动机遇到没匹配上的字符时要跳回的状态,
例如 ababaa,其中字符代表要匹配的输入,数字代表状态
于是有失败函数,此函数满足一个映射,就是next数组,这个串的失败函数是
s a b a b a a
f 0 0 1 2 3 1
失败函数中数字代表的状态是上面串的最长真后缀,例如
s=3时串为aba,f=1串为a,于是a是aba的最长真后缀。
失败函数的作用,当s=3时输入的字符没匹配上,那么自动机就会从3状态跳回1状态,
因为1对应的串是3的最长真后缀,直到3之前都被匹配上了,那么3的最长真后缀也就被匹配上了,
即直到1被匹配上了,所以这样就避免了重复的匹配。
举例,判断上面的字符串是否是abababaab的字串,
首先ababa都被匹配,到下一个a时没匹配上于是跳到f(5)=3,跳到3,即aba是ababa的最长真后缀,
所以aba肯定会被匹配(因为ababa能被匹配),然后baab也被匹配,就是这个过程。
根据上边的话,我理解next数组,保存的就是当前位置最长真后缀,相信你也是茅厕顿开了吧.
下边看算法:
next数组求法:
kmp查找算法(跟next求法神似):
希望对读者有所帮助^_^
下边介绍一个扩展的用法:
“GOOD”串
总提交:266 测试通过:33
描述
Cc最近对字符串很感兴趣,由其对一个字符串的子串的子串作了研究。如果一个字符串A的子串和另一个给定的字符串B相等,他会很高兴,并且把A称作B的Good String。
现在有两个很长的字符串,Cc想知道第一个字符串的某些子串是否是第二个字符串的Good String,于是Cc会询问你第一个字符串的从第a位到第b位的子串是否是第二个字符串的Good String,若是则回答“Yes”,否则回答“No”。
输入
多组数据,每组数据第一行2个数L1,L2(1<=L1,L2<=100000)表示两个字符串的长度,接下来两行是分别是长度为L1和L2的字符串(由小写字母构成),接下来一行一个数Q,表示询问的个数。接下来Q行每行两个数a,b(1<=a<=b<=L1)表示询问第一个字符串的从第a位到第b位的子串是否是第二个字符串的Good String。输入数据以0 0结束。
输出
每组数据输出一个数T占一行,表示Q个询问中回答“Yes”的个数。
样例输入
7 3
abcdefg
def
3
1 7
2 6
3 5
0 0
样例输出
2
考查的就是kmp+二分查找