KMP是个很神奇的算法。
这是一道模板题。
设$S$为模式串,$T$为查询串。
由于正常的字符串匹配实在太慢($O(n^2)$),所以就要考虑这一位匹配不成功时需要移至模式串的哪一位继续匹配。
可以发现,应该移到与当前匹配到的位置的后缀相等的最长前缀。
所以,对于每一个位置$i$,记录$fail_i$为当前匹配到的位置的后缀相等的最长前缀的结束位置。
首先设置初始值$fail_0=-1$。
$fail_i$的求法是这样的:首先看$f=fail_{i-1}$,如果$S_{f+1}\neq S_i$(下标从$0$开始),就是说这个前缀不与当前的后缀匹配,就应该将$f$设为$fail_f$,如此继续。直到$S_{f+1}=S_i$或者$f=-1$为止。那样就将$fail_i$设置为$f+1$。
匹配的时候也是看当前匹配到查询串的位为$i$,模式串的位为$f$,如果$S_{f+1}\neq T_i$,则说明当前位不匹配,则需要将$f$设为$fail_f$,如果还不匹配,则如此继续。最后看是否匹配到了最后一位即可。