POJ 3461

  一道KMP算法的基础题,用于熟悉KMP算法和求next数组,关于KMP算法,为自己写了一篇总结

  这道题要注意的是,模式串可以重叠,比如给出ACA与ACACACA,应该出现了3次,这里只需要在KMP的函数里稍微改动一下即可:如果模式串的位置等于了模式串的长度,说明模式串已经被完整地匹配了,并且,此时模式串的位置由于等于了长度,所以这里是并没有字符的,但next值会存在(详情见求next数组的值的函数),此时只需要假设它们不匹配,转到此时的next值即可。

#include<stdio.h>
#include<string.h>
#define MAX_WORD 10005
#define MAX_TEX 1000005
char s[MAX_TEX],p[MAX_WORD];
int next[MAX_WORD],ans;
void get_next(void);
void kmp(void);
int main()
{
    int n;
    scanf("%d",&n);
    while(n--)
    {
    scanf("%s",p);
    scanf("%s",s);
    ans=0;
    kmp();
    printf("%d\n",ans);
    }
    return 0;
}
void kmp(void)
{
    int lenP=strlen(p),lenS=strlen(s),i,posP=0,posS=0;
    for(i=0;i<=lenP;i++)
    {
    next[i]=0;
    }
    get_next();
    while(posS<lenS)
    {
    if(posP==-1||p[posP]==s[posS])
    {
        posP++;posS++;
        if(posP==lenP)
        {
            ans++;
            posP=next[posP];
        }
    }
    else
    {
        posP=next[posP];
    }
    }
}
void get_next(void)
{
    int i=0,j=-1,len=strlen(p);
    next[0]=-1;
    while(i<len)
    {
        if(j==-1||p[i]==p[j])
        {
            i++;//如果i=len-1,执行这步会使next[len]存在
            j++;
            next[i]=j;
        }
        else
        {
            j=next[j];
        }
    }
}
posted @ 2012-08-11 17:01  等待电子的砹  阅读(134)  评论(0)    收藏  举报