Cod sursa(job #1451030)

Utilizator alex_HarryBabalau Alexandru alex_Harry Data 15 iunie 2015 20:00:43
Problema Aho-Corasick Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 2.33 kb
#include <fstream>
#include <cstring>

using namespace std;

ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");

struct Trie
{
    Trie * Son[26];
    Trie * Fail;
    int Index;
    int Frequency;

    Trie()
    {
       memset(Son,0, sizeof(Son));
       Fail = 0;
       Index = Frequency = 0;
    }

};

const int NMax = 1000005;
const int LMax = 10005;


char String[NMax];
int Sol[NMax];
int N,K;
Trie * T = new Trie;
Trie * Q[LMax * LMax];


void Insert(Trie * Node, char * S,int Idx)
{
    if(!isalpha(*S))
    {
        Node->Index = Idx;
        return;
    }
    if(Node->Son[*S-'a']==0)
    {
        Node->Son[*S-'a'] = new Trie;
    }
    Insert(Node->Son[*S-'a'],S+1,Idx);
}

void Read()
{
    fin>>String;
    fin>>N;
    for(int i = 1; i <= N; i++)
    {
        char S[10005];
        fin>>S;
        Insert(T,S,i);
    }
}

void BFS()
{
    T->Fail = T;
    Q[1] = T;
    K = 1;
    for(int i = 1; i<=K; i++)
    {
        Trie * Node = Q[i];

        for(int i = 0; i < 26 ; ++i)
        {
            Trie *  Fiu = Node->Son[i];
            if(!Fiu) continue;

            Trie * Current_Fail = Node->Fail;

            while(Current_Fail->Son[i]==0 && Current_Fail!=T)
                Current_Fail  = Current_Fail->Fail;

            if(Current_Fail ==T && T->Son[i]==0)
                Fiu->Fail = Current_Fail;
            else
                Fiu->Fail = Current_Fail->Son[i];

            if(Fiu -> Fail == Fiu)
                Fiu->Fail = T;

            Q[++K] = Fiu;
        }
    }

    T->Fail = 0;

}

void Parse()
{
    Trie * Node = T;

    for(int i = 0; String[i]; ++i)
    {
        int Ch = String[i] - 'a';

        while(Node -> Son[Ch]==0 && Node != T)
            Node = Node -> Fail;

        if(Node->Son[Ch])
        {
            Node = Node->Son[Ch];
            Node->Frequency++;
        }
    }
}

void AntiBFS()
{
    for(int i = K; i > 0; i--)
    {
        Trie * Node = Q[i];

        if(Node->Fail)
            Node->Fail->Frequency += Node->Frequency;
        Sol [Node->Index] = Node->Frequency;
    }
}

void Print()
{
    for(int i = 1; i<=N; ++i)
        fout<<Sol[i]<<"\n";
}

int main()
{
    Read();
    BFS();
    Parse();
    AntiBFS();
    Print();
    return 0;
}