字符串算法KMP学习记录

KMP算法通过寻找最大前后缀来实现效率的提高,最基础的用法是寻找模式串B在主串A中的位置(出现次数)

KMP模板需要两个函数:pre()找到模式串的next数组;

kmp()实现算法主体;

代码:

#include<bits/stdc++.h>
#define MAXN 10007 //字符串最大长度
using namespace std;

char A[MAXN],B[MAXN];
int P[MAXN],la,lb;

void pre()
{
    p[1]=0;
    int j=0;
    for(int i=1;i<lb;i++)  //每次循环计算的是p[i+1],由于p[1]=0,i从1开始
    {
        while(j>0&&B[j+1]!=B[i+1]) j=P[j];
        if(B[j+1]==B[i+1]) j++;
        
        P[i+1]=j;       //记录算出的值
    }
}

int kmp()
{
    int ans=0,j=0;
    for(int i=0;i<la;i++)  //每次比对A[i+1]和B[j+1],所以i,j初始值都为0
    {
        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;
            j=P[j];
        }
    }
    return ans;
}


int main()
{
    cin>>A+1;       //输入从A[1]开始
    cin>>B+1;         
    m=strlen(B+1);  //记录长度从B[1]开始,从B开始长度是0
    n=strlen(A+1);
    pre();
    kmp();
    for(int i=1;i<=m;i++)
    {
        cout<<P[i];
        if(i!=m) cout<<' ';
    }
}

需要注意的细节

  1. 两个字符串都是从下标为1的位置开始的,在输入和调用strlen()函数求长度时需要注意

  1. pre()中j=0,循环从i=1开始到i<lb结束 ; kmp()中j=0,循环从i=0开始到i<la结束

  1. pre()和kmp()循环中通用部分是

while(j>0&&下一位不相等)j=p[j];

if(下一位相等)j++;

差异部分:pre()循环中第三句是p[i+1]=j //记录下一位的next值

kmp()循环第三句是if(j==lb){ 找到字串,执行特定操作 } //找到子串

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值