Cod sursa(job #941684)

Utilizator costyv87Vlad Costin costyv87 Data 19 aprilie 2013 13:38:58
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.41 kb
//HighFlow
#include <cstdio>
#include <vector>
#include <string>
#include <bitset>
#include <fstream>
#include <string.h>
#include <math.h>
#include <algorithm>
#define fcat(c) while (c!='\n') fscanf(f,"%c",&c)
#define cat(c) while (c!='\n') scanf("%c",&c)
#define For(i,st,dr,k) for (int i=(st);i<=(dr);i+=(k))
#define ll (long long)
#define kfl(i,j) (a[(i)][(j)].c-a[(i)][(j)].f)
#define kk(c) ((c)-'a')
using namespace std;
FILE *f,*g;

struct Trie {
        int nr;
        Trie *fiu[26];
        Trie *fail;
        vector <int> nod;
        Trie()
        {
            memset(fiu,0,sizeof(fiu));
            fail=0;
            nr=0;
        }
        };
Trie *rad=new Trie;

char A[1000100];
char S[10100];
int n;
vector <Trie*> Q;
int sol[110];

void add(int ind)
{
    int i;
    Trie *T=rad;

    for (i=0;S[i]!='\0' && T->fiu[kk(S[i])];T=T->fiu[kk(S[i])],i++);
    if (S[i]=='\0')
    {
        T->nod.push_back(ind);
        return;
    }

    for (;S[i]!='\0' ;T=T->fiu[kk(S[i])],i++)
        T->fiu[kk(S[i])]=new Trie;

    T->nod.push_back(ind);
}

void read()
{
    int i;
    f=fopen("ahocorasick.in","r");
    g=fopen("ahocorasick.out","w");
    fscanf(f,"%s",A);
    fscanf(f,"%d",&n);

    for (i=1;i<=n;i++)
    {
        fscanf(f,"%s",S);
        add(i);
    }
}

void BFS()
{
    int i,j;
    rad->fail=rad;
    Q.push_back(rad);
    Trie *P,*ax;


    for (i=0;i<Q.size();i++)
    {
        P=Q[i];
        for (j=0;j<=25;j++)
            if (P->fiu[j])
            {
                for (ax=P->fail;ax!=rad && !(ax->fiu[j]);ax=ax->fail);
                if (ax->fiu[j] && ax->fiu[j]!=P->fiu[j])  ax=ax->fiu[j];
                P->fiu[j]->fail=ax;
                Q.push_back(P->fiu[j]);
            }
    }
    //rad->fail=0;
}

void  down()
{
    int nn=strlen(A);
    Trie *ax=rad;

    for (int i=0;i<nn;i++)
    {
        while (ax!=rad  && !(ax->fiu[kk(A[i])])) ax=ax->fail;
        if (ax->fiu[kk(A[i])]) ax=ax->fiu[kk(A[i])];
        ax->nr++;
    }
}

void BFS_back()
{
    int i,j;
    Trie *P;

    for (i=Q.size()-1;i>=0;i--)
    {
        P=Q[i];
        if (P->fail)
            P->fail->nr+=P->nr;
        for (j=0;j<P->nod.size();j++)
            sol[P->nod[j]]=P->nr;
    }


}


int main()
{
    read();
    BFS();
    down();
    BFS_back();
    for (int i=1;i<=n;i++) fprintf(g,"%d\n",sol[i]);

	return 0;
}