我对于KMP算法的一点理解

本文深入浅出地介绍了KMP算法的原理与实现过程,通过对比朴素的字符串匹配方法,突出了KMP算法如何利用之前匹配的信息来提高效率,避免不必要的比较。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

KMP算法是很巧妙的,代码又短,它涉及到了我所学到的状态转移的东西,我用这个来理解KMP,效果是比较好的。

首先说一下状态转移,用我的话来说就是转跳,从一个值转跳到另一个值,比如说匹配了3个字符,然后转跳到了匹配了1个字符(注意,这个就是KMP的一个简单描述,后面会详细阐述),从3到1。

另外还会涉及到前缀和后缀,简单的理解就是字符串的前面和后面。

比如说字符串s="abcdefghi",前缀有"a","ab",“abc”,"abcd","abcde","acbdef"等等,后缀有"i", "hi","ghi","fghi","efghi","defghi","cdefghi"。

接着我就来说说朴素的字符串匹配的方法,就是直接暴力匹配。

比如说s="abcdefghi"(目标串),拿“cdef”(模式串)去匹配s,那么一开始从c和a比较,然后发现不匹配,就拿c和b来比较,直到c和c匹配了就继续。

简单的来说就是直接用模式串的开头在目标串的每一个位置来穷举并且验证是不是一模一样的。

而KMP就是在朴素的方法上改进的,KMP方法的关键就在于每一次不匹配之后充分利用之前的匹配的信息来最大程度地移动字符串,减少不必要的比较。

比如说s1=“abcdab”匹配s2=“abcdacabcdab”的时候,第一次匹配失败的时候就是s1[5]='b'匹配s2[5]='c'的时候,朴素的方法是s1滑动一位,KMP则是直接滑动4位,让s2[4]='a'和s1[0]=‘a'匹配之后继续往下比较。

KMP的滑动距离是由和最后一个不匹配的位置决定的,这个函数关系可以称之为失配函数,所有值与字符位置一一对应之后就变成了转跳表(也是状态转移图)next[]。

接着就到了最关键的问题——next[]怎么求,首先要明白next[]的意义,next[i]就是指在字符串第i位失配之后要从next[i]位开始继续比较,对于朴素的方法,next[]=0,失配之后全部从头开始匹配。而求得next[]值的key在于求得当前匹配的字符串中前缀和后缀相等的最长长度。

可以参考一下链接:

http://blog.youkuaiyun.com/joylnwang/article/details/6778316

http://zh.wikipedia.org/wiki/%E5%85%8B%E5%8A%AA%E6%96%AF-%E8%8E%AB%E9%87%8C%E6%96%AF-%E6%99%AE%E6%8B%89%E7%89%B9%E7%AE%97%E6%B3%95

http://www.matrix67.com/blog/archives/115

http://billhoo.blog.51cto.com/2337751/411486/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值