kmp算法是典型的字符串匹配算法。
相对于朴素字符串匹配算法来说,由于其在计算时进行了预处理,
所以在时间复杂度上比朴素字符串匹配算法要高。
其核心在于kmp算法在计算时的预处理。
预处理是干什么呢?
这里我们先给出一个算法导论上面字符串及其预处理结果。
字符串str为ababababca
预处理结果数组为:
[0, 0, 1, 2, 3, 4, 5, 6, 0, 1]
预处理结果数组与字符串的长度是一样的。
对于预处理结果数组result来说,
result[i]=max{x<i,并且str从开始到x的字串是str从开始到i的子串的后缀}
这个可能有点难懂,我们结合实例来分析下,
很明显,
result[0]=0;
看result[1],这里str从开始到i的子串为ab
str从开始到0的子串为a,a不是ab的后缀,所以result[1]=0;
然后看result[2],这里str从开始到i的子串为aba,
str从开始到0的子串为a,a是aba的后缀,str从开始到1的子串为ab,ab不是aba的后缀,
所以result[2]=1;
然后是result[3],这里str从开始到i的子串为abab,
str从开始到0的子串为a,a不是abab的后缀,str从开始到1的子串为ab,ab是abab的后缀,str从开始到2的子串为aba,aba不是abab的后缀,
所以result[3]=2,依次类推。
匹配的时候呢,
假设我们来匹配abababac与aba
就是在abababac中查找aba在何位置出现,
那么,先查找它们的第一位,第二位,第三位,发现都匹配上了,
这个时候,输出第一个结果,但是继续查找的时候与朴素字符串匹配不同。
朴素字符串这个时候从abababac的第二位,aba的第二位开始继续搜索,
但是我们有了预处理的结果,不从aba的第一位开始搜索了,
而是从aba的第二位,abababac的第四位继续搜索。
所以时间复杂度有了提高。
下面是简单的测试程序:
下面是其的一个简单应用:
poj2406链接见:
http://poj.org/problem?id=2406
计算这个字符串被重复了多少次
这里面是kmp预处理算法的应用,
对输入字符串进行预处理,
得到最后一个字符的对应数组值,简单计算后就可以得到结果,
ac程序如下: