您的位置:首页 > 其它

KMP算法学习之(一)学习的感悟

2012-10-22 22:49 316 查看
看KMP算法好几天了!今天有所感悟,就把感悟记录下来吧!这篇文章不讨论KMP算法的细节,因为对于这么一个经典的算法,有很多作者写得相当之深刻与清晰!

比如:July的博客(http://blog.csdn.net/v_JULY_v/article/details/6111565)

在这里向这位大牛致敬!也感谢提供这个博客给我的朋友(张钊)。

KMP算法的关键在于:next数组!我主要也卡在对next数组的理解上。看July的博客的时候,才觉得弄懂了next求的是什么,怎么求!

覆盖函数(overlay_function)

覆盖函数所表征的是pattern本身的性质,可以让为其表征的是pattern从左开始的所有连续子串的自我覆盖程度。
这句话怎么理解呢?还是举具体的实例吧!比如字符串: abaabcaba,它的前缀子串分别是:
a
ab
aba
abaa
abaab
abaabc
abaabca
abaabcab
abaabcaba
,next数组求的就是每个前缀的自我覆盖程度!那什么是自我覆盖呢?
用通俗的话来说:就是后半截与前半截能重叠的长度是多少!比如:
a,只有1个字符,不存在自我覆盖的问题,所以next[0]=-1; (下标从0开始,所以不为0)
ab,也没有重叠,所以next[1]=-1;
aba,好了,有重叠了!最前面的一个字符与最后面的一个字符重叠,所以next[2]=0。只重叠了一个。
abaa,与上面一样,所以next[3]=0;
abaab,最前面的ab与最后面的ab重叠,所以next[4]=1;
abaabc,前面的与后面的不会重叠,因为前面没有c这个字符,所以next[5]=-1;
abaabca,只重叠了一个字符,next[6]=0;
abaabcab,重叠了两个字符,next[7]=1;
abaabcaba,重叠了aba三个字符,所以next[8]=2.
OK,next数组就出来了!
当然这个只是我们自己直观的判断,那用程序怎么实现呢?
July的博客上提到,可以用递推来实现!主要分两种情况:

计算这个overlay函数的方法可以采用递推,可以想象如果对于pattern的前j个字符,如果覆盖函数值为k
a0a1...ak-1ak=aj-kaj-k+1...aj-1aj

则对于pattern的前j+1序列字符,则有如下可能

⑴ pattern[k+1]==pattern[j+1] 此时overlay(j+1)=k+1=overlay(j)+1

⑵ pattern[k+1]≠pattern[j+1] 此时只能在pattern前k+1个子符组所的子串中找到相应的overlay函数,h=overlay(k),如果此时pattern[h+1]==pattern[j+1],则overlay(j+1)=h+1否则重复(2)过程.
(摘自July的博客)
这样,KMP算法的核心就弄明白了!接下来的问题就只剩下字符串与pattern不匹配时跳转的步数问题了!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  KMP算法