kmp算法再理解

next数组表示失配时,子串应该移向的位置
所以当时失配才考虑用next数组

通过移动子串p来寻找p在s串中出现的位置。
next[j]用来记录当s[i]和p[j]匹配不成功时,j从next[j]开始重新匹配
next数组表示当前字符之前的字符串中,最长相同前后缀长度。
kmp算法步骤:
当j=-1(p串从头开始匹配)或者s[i]和p[j]匹配时,{ i++; j++; }
当j!=-1且s[i]和p[j]不匹配时,{ i不变,j=next[j] } ;表示失配时,p串向右移动j-next[j]位
大神巨厉害详解

/*不要用next做数组名,与c++库函数next重复,会出CE*/
#include<bits/stdc++.h>
using namespace std;
int fff[150];
void getnextt(char p[])
{
    int i,j,len;
    i=0; j=-1; fff[0]=-1;//next初值赋为-1
    len=strlen(p);
    while(i<len-1)
    {
        if(j==-1||p[j]==p[i])//p[j]表前缀,p[i]表后缀(前后缀相同时)
        {
            ++i;
            ++j;
            if(p[i]!=p[j])//p[i]!=p[fff[i]],,匹配3.3.8
            {
                fff[i]=j;
            }
            else
                fff[i]=fff[j];//如果相同,i的next返回相同前缀处的next
        }
        else//前后缀不相同时,j递归找长度变小的相同前缀.。。匹配3.3.4问题2
            j=fff[j];
    }
}
int kmp(char s[],char p[])
{
    int i,j,len1,len2;
    len1=strlen(s);
    len2=strlen(p);
    i=0;
    j=0;
    while(i<len1&&j<len2)
    {
        if(j==-1||s[i]==p[j])//j=-1表模板串从头开始开始匹配,s串从下一位开始继续匹配
        {
            i++;
            j++;
        }
        else//匹配不相同,模板串从next[j]开始继续匹配,模板串向右移动j-next[j]位
            j=fff[j];
    }
    if(j>=len2)
        return i-len2;
    else
        return -1;
}
int main()
{
    char s[150],p[150];
    while(cin>>s>>p)
    {
        getnextt(p);
        int ans=kmp(s,p);
        cout<<ans<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值