KMP详解

KMP 算法又称看毛片算法,运用于字符串匹配问题
它的优秀性在于复杂度低而且不止能解决字符串相等的匹配问题
还可以根据题目的需要写个 check 函数解决一些另类的字符串问题
对于字符串匹配问题,最暴力的做法是这样的:
这里写图片描述
当匹配串 A (蓝的)与待匹配串B(黑的)在如图棕色下标处( Aij+1Bj )匹配失败或匹配结束时
我们将匹配串的下标返回 1 ,然后待匹配串的下标返回i+1
于是我们发现这样的算法很不优秀
这样一直讲下标i往回弹显然是不可取的
于是我们开始思考怎么让 i 不往回弹呢?
显然不将i往回弹时,我们需要知道一个最小的下标 k
满足A[k,i1] B 的前缀,
然而我们发现既然匹配到了i才失败,那么就表示 A[i+j1,i1]==B[1,j1]
所以我们即需要知道一个最小的下标 k ,满足B[k,j1]==B[1,jk]
一般我们称这个 k failj
即当匹配串在下标j处匹配失败时,下标将会跳转到的位置
就不画图了,烦。。。。。
那么这个位置怎么求呢?
我们只需要用匹配串和匹配串自己匹配一次,每次找到一个最长的前缀等于当前后缀即可
当然这个时候也不能直接暴力判相等啊。。。
当判断 [i,i+j1],[1,j] 是否相等时, [i,i+j2],[1,j1] 已经相等
所以只需判断 [ij1,ij1],[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){
            //处理答案,看题目想干嘛
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值