Cod sursa(job #799662)

Utilizator BlaugranasEnal Gemaledin Blaugranas Data 19 octombrie 2012 18:09:41
Problema Aho-Corasick Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.58 kb
#include<cstdio>
#include<cstring>
struct edge
{char c;
struct N_t *next;};

struct P
{int b;
char *a;};

struct N_t
{int f,d,mpn,od,ann;
struct N_t *fn,**an; 
char **mp;
edge *o;
N_t()
     {memset(this,0,sizeof(N_t));
     this->o=new edge[2];
     this->mp=new char*[100];
     this->an=new N_t*[10001];}};

N_t *r,*next,*thiz=new N_t();
int i,n,b[101],j,k,o[101],l,e,p,u;
char s[1000001],a[101][10001],c[101],q[10001];
P d[101];

N_t *find_next(N_t *thiz,char c)
{for(int i=0;i<thiz->od;i++)
if(thiz->o[i].c==c)
    return thiz->o[i].next;
return NULL;}

int has_matchstr(N_t *thiz,char *newstr)
{int k=strlen(newstr);
for(int i=0;i<thiz->mpn;i++)
if(strlen(thiz->mp[i])==k)
     for(int j=0;j<k;j++)
     if(thiz->mp[i][j]==newstr[j])
           return 1;
return 0;}
		
void traverse_setfailure(N_t *thiz,N_t *node,char c[])
{for(int i=0;i<node->od;i++)
	{c[node->d]=node->o[i].c;
	N_t *r=node->o[i].next,*m;
	if(!r->fn)
	        r->fn=thiz;
    for(int j=1;j<r->d;j++)
            {m=thiz;
            for(int k=j;k<r->d&&m;k++)
                   m=find_next(m,c[k]);
            if(m)
                   {r->fn=m;
                   break;}}
	traverse_setfailure(thiz,node->o[i].next,c);}}

int main()
{freopen("ahocorasick.in","r",stdin),freopen("ahocorasick.out","w",stdout);
gets(s),scanf("%d\n",&n);
thiz->an[thiz->ann++]=thiz;
for(l=0,j=1;j<=n;j++)
	{gets(a[j]),r=thiz;
    for(i=1;!o[j]&&i<j;i++)
    if(!strcmp(a[j],a[i]))
           o[j]=i;
    if(!o[j])
           {d[l].a=a[j],d[l++].b=j;
           for(i=0;a[j][i];i++)
           if((next=find_next(r,a[j][i])))
                  r=next;
           else
                  {r->o[r->od].c=a[j][i],r->o[r->od].next=new N_t();
                  r->o[r->od].next->d=r->d+1,thiz->an[thiz->ann++]=r=r->o[r->od++].next;}
           if(!has_matchstr(r,a[j]))
                  r->mp[r->mpn++]=a[j];
           r->f=1;}}
traverse_setfailure(thiz,thiz,c);
for(i=0;i<thiz->ann;i++)
for(N_t *m=thiz->an[i]->fn;m;m=m->fn)
      {for(int j=0;j<m->mpn;j++)
      if(!has_matchstr(thiz->an[i],m->mp[j]))
            thiz->an[i]->mp[thiz->an[i]->mpn++]=m->mp[j];   
       if(m->f)
            thiz->an[i]->f=1;}
while(s[k])
if(!(next=find_next(thiz,s[k])))
      if(thiz->fn)
            thiz=thiz->fn;
      else
            k++;
else
      {thiz=next,k++;
      if(thiz->f)
            for(i=0;i<l;i++)
            for(j=0;j<thiz->mpn;j++)
            if(thiz->mp[j]==d[i].a)     	      
                   b[d[i].b]++;}
for(i=1;i<=n;i++)
     printf("%d\n",!o[i]?b[i]:b[o[i]]);
return 0;}