KMP——字符串匹配算法

KMP算法挺抽象,第一次接触理解不够深,以后通过题目慢慢了解。

设字符串a长度为n,待匹配子串b的长度为m,暴力枚举法的时间复杂度为log(m*n)
而KMP算法的时间复杂度为log(m+n),因为指向主串i只增不减,避免了多余的回溯。

算法内容:
首先构造一个数组P
P[i]存储的是b串前i个字符前缀和后缀相同的最大字符个数
例如b=“ababa”,则p={0,0,1,2,3}
然后是匹配过程,例如:
在这里插入图片描述
若让b向右移动一格是没必要的,利用已经预处理好的数组p可以让b向右移动一个前缀的距离,只需j=p[j],而p[5]为3,即从i== 5,j== 3开始匹配,如下图
在这里插入图片描述
一道例题(HOJ):剪花布条

#include<bits/stdc++.h>
using namespace std;
char b[1005],a[1005];

int kmp(char a[],char b[]){//a和b都是从下表为1开始存储!!
    int res=0,j=0,m=strlen(b+1),n=strlen(a+1),p[1005]={0};
    for(int i=1;i<m;i++){
            while(j>0&&b[j+1]!=b[i+1])j=p[j];
            if(b[i+1]==b[j+1])j++;
            p[i+1]=j;
        }
        j=0;
        for(int i=0;i<n;i++){
            while(j>0&&b[j+1]!=a[i+1])j=p[j];
            if(b[j+1]==a[i+1])j++;
            if(j==m){
                //cout<<i-m+2<<endl;  //输出下表对应位置
                res++;
                //j=p[j]; //aaaaa aa  输出:4
                j=i+2; //aaaaa aa  输出:2
                //注意对比两种匹配方式,按要求随机应变
            }
        }
        return res;
        //根据要求返回
}

int main(){

    ios::sync_with_stdio(0);
    while(cin>>a+1){
        if(a[1]=='#')break;
        cin>>b+1;
        cout<<kmp(a,b)<<endl;
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值