kmp算法

得到next函数:覆盖函数(overlay_function)

覆盖函数所表征的是pattern本身的性质,可以让为其表征的是pattern从左开始的所有连续子串的自我覆盖程度。
比如如下的字串,abaabcaba

由于计数是从0始的,因此覆盖函数的值为0说明有1个匹配,对于从0还是从来开始计数是偏好问题,

具体请自行调整,其中-1表示没有覆盖,那么何为覆盖呢,下面比较数学的来看一下定义,比如对于序列

a0a1...aj-1 aj

要找到一个k,使它满足

a0a1...ak-1ak=aj-kaj-k+1...aj-1aj

而没有更大的k满足这个条件,就是说要找到尽可能大k,使pattern前k字符与后k字符相匹配,k要尽可能的大,
原因是如果有比较大的k存在,而我们选择较小的满足条件的k,
那么当失配时,我们就会使pattern向右移动的位置变大,而较少的移动位置是存在匹配的,这样我们就会把可能匹配的结果丢失。

http://acm.nyist.net/JudgeOnline/problem.php?pid=5练习。

#include<stdio.h>
#include<string.h>
int next[12];
void get_next(char *p,int len)
{
    int j=1;
    next[0]=-1;
    int k=-1;
    for(;j<len;j++)
    {
        while(k>-1&&p[k+1]!=p[j]) k=next[k];
        if(p[k+1]==p[j]) k++;
        next[j]=k;
    }
}
int main()
{
    freopen("Input.txt","r",stdin);
    int ncase,i,j;
    char s[1002],p[12];
    scanf("%d",&ncase);
    while(ncase--)
    {
        scanf("%s %s",p,s);
        get_next(p,strlen(p));
        int num=0;
        i=0;j=-1;
        while(i<strlen(s))
        {
            while(j>-1&&p[j+1]!=s[i]) j=next[j];
            if(p[j+1]==s[i]) j++;
            i++;
            if(j==strlen(p)-1) { num++;j=next[j]; }
        }
        printf("%d\n",num);
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值