zoj 3228 Searching the String

给你一个主串

再给你很多模式串

对于每个串分别判断它在主串中出现了几次

每个模式串还有一个flag标记 0:匹配的时候可以重叠  1:匹配的时候不能重叠

在匹配的时候判断当期节点上一次匹配的时候在主串中的位置与当前位置之差是否大于模式串的长度即可

View Code
#include<cstdio>
#include<cstring>
const int MM = 500005,NC = 26;
int N;
char str[100010];
char s[100010];
int x[100010];
int flag[100010];
struct trie{
    int ch[NC],fail,f[2],pos,len;
    void init(){
        memset(ch,0,sizeof(ch));
        fail=f[0]=f[1]=len=0;
        pos=-1;
    }
}a[MM];
int cnt,rt,q[MM],front,last;
void Init(){
    cnt=1;
    rt=cnt++;
    a[0].init();
    for(int i=0;i<NC;i++)   a[0].ch[i]=rt;
    a[1].init();
    memset(x,0,sizeof(x));
}
void Ins(char *in,int flag,int num){
    int now=rt,i=0;
    for(;*in;++in){
        i++;
        int id=*in-'a';
        if(!a[now].ch[id]){
            a[cnt].init();
            a[now].ch[id]=cnt++;
        }
        now=a[now].ch[id];
    }
    a[now].len=i;
    a[now].f[flag]=1;
    x[num]=now;
}
void build(){
    front=last=0;
    q[front++]=rt;
    while(last<front){
        int t=q[last++];
        for(int i=0;i<NC;i++){
          int tt=a[t].ch[i];
          int ff=a[t].fail;
          if(a[t].ch[i]){
              a[tt].fail=a[ff].ch[i];
              q[front++]=tt;
          }
          else  a[t].ch[i]=a[ff].ch[i];
        }
    }
}
void AC(char *str){
    int i=0,cur=rt;
    for(;str[i];i++){
        int id=str[i]-'a';
        cur=a[cur].ch[id];
        int p=cur;
        while(p!=rt)
        {
            if(a[p].f[0]) a[p].f[0]++;
            if(a[p].f[1]) 
            {
                if(i-a[p].pos >= a[p].len)
                {
                    a[p].pos=i;
                    a[p].f[1]++;
        }
        }
            p=a[p].fail;
        }
    }
}
int main(){
    int t,n,ca=0,i;
    while(scanf("%s",s)!=EOF){
        Init();
        scanf("%d",&n);
        for(i=1;i<=n;i++){
            scanf("%d%s",&flag[i],str);
            Ins(str,flag[i],i);
        }
        build();
        AC(s);printf("Case %d\n",++ca);
        for(i=1;i<=n;i++)
        {
            printf("%d\n",a[x[i]].f[flag[i]]-1);
        }
        puts("");
    }
    return 0;
}
posted @ 2012-05-19 23:57  Because Of You  Views(331)  Comments(0Edit  收藏  举报