HDU 1686 Oulipo , 同 POJ 3461 Oulipo (字符串匹配,KMP)

HDU题目

POJ题目

 

求目标串s中包含多少个模式串p

 

KMP算法,必须好好利用next数组,,

 (kmp解析)——可参考 海子的博客  KMP算法

 

 //写法一:

#include<string>
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>

using namespace std;

void getNext(char *p,int *next)
{
    int j,k;
    int lenp=strlen(p);
    next[0]=-1;
    j=0;
    k=-1;
    while(j < lenp)
    {
        if(k==-1||p[j]==p[k])    //匹配的情况下,p[j]==p[k]
        {
            ++j;
            ++k;
             
            //若p[j]==p[k],则需要修正
            if(p[j]==p[k])  
                next[j]=next[k];
            else
                next[j]=k;
        }
        else                   //p[j]!=p[k]
            k=next[k];
    }
}

int KMPMatch(char *s,char *p)//返回s中包含p的个数
{
    int next[10010]; //注意next数组的长度要和匹配的字符串长度一样
    int lens=strlen(s),lenp=strlen(p);
    int i,j,ans=0;
    i=0;
    j=0;
    getNext(p,next);
    while( i < lens )
    {
        if(j==-1||s[i]==p[j])
        {
            i++;
            j++;
        }
        else
            j=next[j];       //消除了指针i的回溯
        if(j==lenp)
        {
            ans++;
            j=next[j];   //再根据next数组从"前"一个找起,防超时,,
        }
    }
    return ans;
}

char str[1000010],word[10010];

int main()
{
    
    int n;
    scanf("%d",&n);
    while(n--)
    {
        scanf("%s%s",word,str);
        int ans = KMPMatch(str,word);
        printf("%d\n",ans);
    }
    return 0;
}
View Code

 

 

//写法二:

#include <stdio.h>
#include <string.h>

int lens,lenp;
char s[1000005];
char p[10005];
int next[10005];

void get_next(int lenp, char *p, int *next)//求next数组
{
    int i,j;
    j=-1;
    next[0]=-1;
    for (i=1;i<lenp;i++)
    {
        while(j>=0 && p[j+1]!=p[i]) j=next[j];
        if (p[j+1]==p[i]) j++;
        next[i]=j;
    }
}

int kmp_num(char *s, char *p, int lens,int lenp) //返回s当中包含多少个p
{
    int i,j,cnt;
    cnt=0;
    j=-1;
    for (i=0;i<lens;i++)
    {
        while(j>=0 && p[j+1]!=s[i]) j=next[j];
        if (p[j+1]==s[i]) j++;
        if (j==lenp-1) cnt++;
    }
    return cnt;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%s",p);
        scanf("%s",s);
        lens=strlen(s);
        lenp=strlen(p);
        get_next(lenp,p,next);
        printf("%d\n",kmp_num(s,p,lens,lenp));
    }
    return 0;
}
View Code

 

posted @ 2014-07-07 23:58  laiba2004  Views(139)  Comments(0Edit  收藏  举报