KMP算法理论

举个栗子:
给出:
一个文本串:aabaabaaf
一个模式串:aabaaf

求文本串里是否出现过这个模式串。

逐一匹配,当到达f的时候,发现不匹配,回到b的位置重新匹配。
b的后缀是aa,前缀也是aa,因为发现了在f处不匹配,所以在f前面的子串的后缀是aa,我们就找到与这个后缀相等的前缀的后面一个字母重新开始匹配,这个字母就是b。
因此在这道题目里,最重要的是求出一个字符串里的最长相等前后缀。也就是当遇到不匹配的字母的时候,找它之前这个子串的最长相等前后缀是多少,在这个题目中很明显会跳到下标为2的位置(b),所以选择前缀表来解决这个问题。

怎么求前缀表:

先明白一个概:什么是前缀,什么是后缀
以这个字符串为例:aabaaf。
前缀: 包含首字母不包含尾字母的所有子串,都称为前缀。
上述字符串的前缀子串有:a,aa,aab,aab,aabaa

后缀: 只包含尾字母,不包含首字母的所有子串。
上述字符串的后缀子串有:f,af,aaf,baaf,abaaf

求最长相等前后缀:

依旧拿aabaaf举例。
子串--------------- 最长相等前后缀长度----------------------原因:
a-----------------------------0-----------------------因为a既是首字母也是尾字母
aa---------------------------1-----------------------前缀是a,后缀也是a
aab-------------------------0-----------------------后缀有b,找不到与其相等的前缀
aaba-----------------------1-----------------------前面的a和最后的a,只有一个相等的前后缀
aabaa---------------------2------------------------前后两个a
aabaaf--------------------0------------------------找不到
得到的这个长度序列:0,1,0,1,2,0.就是这个模式串前缀表。

写成如下的方式:
索引: 0 1 2 3 4 5
字串: a a b a a f
前缀表:0 1 0 1 2 0

当遍历到f时,发现不匹配,开始寻找f前面这个子串的最长相等前后缀是多少,发现是2,意味着有一个后缀aa,前面也有一个与其相等的前缀aa,我们在这个后缀aa的后面(f)处不匹配了,找与其相等的前缀的后面开始重新匹配,这里通俗来说就是找前缀表中最大值(2)与索引相等的位置开始匹配,索引为2的地方即b。

你可能感兴趣的:(算法题,c++,算法)