字符串系列(三)——匹配算法KMP

KMP算法,是处理字符串模式匹配问题的。能够在线性时间判断模式串在主串中出现的次数(如果根本不是子串,输出0)。

这个时候我要再安利一手Hash。Hash也能在线性时间解决!!!!(众人:你不是要说KMP吗)啊对,让我们来看看今天的主角。KMP算法的核心,就是其next数组,这个next数组往往可以解决许多问题。

现给出定义:next[i]表示模式串(短的内个)中以i结尾的非前缀子串与A的前缀能匹配上的最大长度。

即:next[i] = max{j},且j要满足j < i且str[i - j + 1~i] = str[1~j]。

这是怎么想出来的呢.......先看匹配的常规方法,一位一位匹配,假设匹配到某一位就不对了,常规来说是O(n²)的处理,退两个指针再匹配。但我们想充分利用已匹配那一段的特点。如果前面已经匹配成功的一段里,有和前缀相同的,我们才有继续匹配这段的价值。

就比如说,两个串:

xxxxxxyyyyyyyy

xxxxyyyy

这个时候由于前面有相似的,我们可以直接只挪动模式串指针,从如下开始匹配:

xxxxxxyyyyyyyy

  xxxxyyyy

发现还不行,怎么办呢?所以我们再错后,就得到了答案。

next数组正是O(1)的为我们提供了每次移动后的位置。

对两串匹配可以得到数组f,f[i]表示主串中以i结尾的子串与A的前缀能匹配的最长长度。二者求法十分相似。

贴一个李煜东前辈模板吧:

next[1] = 0;
for(int i = 2, j = 0; i <= n; ++i) {
	while(j > 0 && str[i] != str[j + 1]) j = next[j];
	if(str[i] == str[j + 1]) j++;
	next[i] = j;
}
for(int i = 1, j = 0; i <= m; ++i) {
	while(j > 0  && (j == n || str1[i] != str[j + 1])) j = next[j];
	if(str1[i] == str[j + 1]) j++;
	f[i] = j;
	//if(f[i] == n),则是模式串在主串中的一次出现 
}

就介绍到这吧。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值