字符串系列(三)——匹配算法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),则是模式串在主串中的一次出现 
}

就介绍到这吧。

    原文作者:KMP算法
    原文地址: https://blog.csdn.net/Richard_for_OI/article/details/79309484
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞