KMP 模式匹配算法

KMP是一个用来匹配字符串的算法,即在一个字符串里面找到给定子串的位置。一般情况下我们在字符串主串中查找一个子串,最直接的办法是设置两个游标,从前往后逐一比较字符串中的单个字符,如果字符相同,那么两个游标同时递增,直到子串游标指向最后一个字符为止则匹配成功。算法如下

<span style="font-size:24px;">i=0,j=0;
while( i<=主串.length && j<=子串.length){
	if( 主串[i] == 子串[j] ) { 
		i++ ; j++ ; 
	}else{
		 i = i - j + 1; 
	}
}</span>


最终退出循环,如果i < 主串.length 那么  i-j的差就是子串在主串中的位置,否则不到子串



在循环中当主串i位字符与子串j位字符不等时,主串游标需要回溯(放弃已匹配部分,从头开始),例如:

主串  a b a a b ab a a b c      

子串  a b a a b c 

(序号 1  2  3  4  5  6  7  8  9  10 11 )

游标序号i、j从1指到5,字符都相同,再一次同时递增后,i、j都指向6,发现字符"a"与字符"c"不同,i回溯从2开始,同时j又从1开始,进行下一回合比较。。。

最糟糕的情况,时间复杂度会达到 O(主串长度 * 子串长度)


KMP算法可以让时间复杂度在最糟糕的情况下保持在 O(主串长度 + 子串长度)。

该算法可以保证在主串游标 i 不需要回溯的情况下匹配字符串。

在上面例子中,当i、j都指向6的时候发现字符不同,i不回溯,而是改变子串的游标j,让它指向3,此后主串[6] 跟子串[3]比较,主串[7]跟子串[4]比较,主串[8]跟子串[5]比较,主串[9]跟子串[6]比较,如同滑动了子串跟主串对比的位置

主串  a b a a b b a a b c(序号1-11)

子串             a b a a b c(序号1-6)

如此一来i仍旧指向6,j则从3开始继续匹配,子串已经匹配过的部分就不用匹配了。这是原先字符串匹配算法的一种改进。算法的关键在于新的j的值如何取得


当发生“不匹配”的时候 j 指向的位置新位置next[ j ]定义如下

1、next[ 1 ] = 0   当 j == 1时

2、如果模式串中存在最大的 k ( 1 < k < j ),使得模式串中位置1到k-1的字符与

     位置j-k+1到j-1的字符相同,那么next[j]=k。

3、除了以上2种情况,其它next[j]=1



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值