KMP
算法又称看毛片算法,运用于字符串匹配问题
它的优秀性在于复杂度低而且不止能解决字符串相等的匹配问题
还可以根据题目的需要写个
check
函数解决一些另类的字符串问题
对于字符串匹配问题,最暴力的做法是这样的:
当匹配串
A
(蓝的)与待匹配串
我们将匹配串的下标返回
1
,然后待匹配串的下标返回
于是我们发现这样的算法很不优秀
这样一直讲下标i往回弹显然是不可取的
于是我们开始思考怎么让
i
不往回弹呢?
显然不将
满足
然而我们发现既然匹配到了
所以我们即需要知道一个最小的下标
k
,满足
一般我们称这个
k
为
即当匹配串在下标j处匹配失败时,下标将会跳转到的位置
就不画图了,烦。。。。。
那么这个位置怎么求呢?
我们只需要用匹配串和匹配串自己匹配一次,每次找到一个最长的前缀等于当前后缀即可
当然这个时候也不能直接暴力判相等啊。。。
当判断
[i,i+j−1],[1,j]
是否相等时,
[i,i+j−2],[1,j−1]
已经相等
所以只需判断
[i−j−1,i−j−1],[j,j]
是否相等即可,就得到的一个很好的优化
这使整个
KMP
复杂度有了更好的保证
模板:
void Get_KMP(int m){//匹配串造fail
fail[1]=0;fail[2]=1;
for(int i=2,j;i<=m;i++){
j=fail[i];
while(j&&B[i]!=B[j])j=fail[j];
fail[i+1]=j+1;
}
}
void match(int n,int m){//匹配待匹配串
for(int i=1,j=1;i<=n;i++){
while(j&&A[i]!=B[j])j=fail[j];
j++;
if(j==m+1){
//处理答案,看题目想干嘛
}
}
}