ch1(数据结构篇)——KMP

1.自然语言描述

KMP 算法是用来寻找模式串S中的模板串P,看是否存在,或P在S中出现了多少次;暴力法解决字符串匹配问题时,当P在S的当前位置不能匹配时,向后移动一位继续匹配,每次都从P的开头进行匹配,时间复杂度O(nm)级别;可以发现暴力法中P不断向后移的过程中,没有利用之前匹配的信息,这些信息可以让P向后移动更多的距离,也就是利用next数组,每次不一定非要从P的开头进行匹配,KMP 利用模板串P每个位置上最大的前缀后缀相同长度来节省时间。

KMP 算法的核心是next数组。next数组的含义是:设当前位置为i,next[i]={P(1,i)前缀和后缀相同时的最大长度} i∈(1,n) n为P长度。

2.代码描述
题目:Acwing.831 KMP字符串题目链接

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int MAXN=1e6+10;
int ne[MAXN],n,m;
char s[MAXN],p[MAXN];

int main(void)
{
    
    cin>>n>> p+1>>m>> s+1;
    
    //求next数组
    for(int i=2,j=0;i<=n;i++){//i从2开始,因为只有第一个元素的子串不含非平凡前后缀。
        while(j&&p[i]!=p[j+1]) j=ne[j];
        //这里对应了两种情况结束循环(匹配)
        //1.如果始终找不到合适的公共前后缀使得i和j+1相等,用完了ne的信息,则说明(1,i)这个子串没有公共前后缀(ne[i]=0)
        //2.如果因为i和j+1相等跳出循环,则说明(1,i)这个字串的最大公共前后缀长度为(1,j+1)的长度(纸上画图可以很清楚的表现出来)
        //	那么就可以更新ne[i]了,ne[i]=j+1;
        if(p[j+1]==p[i]) j++;
        ne[i]=j;
    }
    
    //和求next数组时一样的匹配方法
    for(int i=1,j=0;i<=m;i++){
        while(j&&s[i]!=p[j+1]) j=ne[j];
        //类似的
        //1.j==0时,S(i-j+1,i)中没有能够与P匹配的子串
        //2.S(i-j+1,i)与P(1,j+1)匹配了
        if(p[j+1]==s[i]) j++;
        //如果j+1后得到的j==n,则说明S(i-j+1,i)与P串完全匹配了
        if(j==n){
            printf("%d ",i-n);
            j=ne[j];//P可能在S中不只出现一次,所以要接着滑动P串继续匹配
        }
    }
    
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值