Cod sursa(job #1482004)

Utilizator DrumeaVDrumea Vasile DrumeaV Data 5 septembrie 2015 19:30:58
Problema Aho-Corasick Scor 25
Compilator cpp Status done
Runda Arhiva educationala Marime 2.13 kb
#include <fstream>
#include <queue>
#include <vector>
#include <string.h>

using namespace std;

const int MA = 1000005;
const int ML = 10005;
const int MN = 105;

struct Trie
{
    int Nr;
    Trie *Sons[26], *Sfx;
    vector< Trie* > V;

    Trie()
    {
        Nr = 0;
        Sfx = 0;
        memset(Sons,0,sizeof(Sons));
    }
};

int N;
char A[MA],B[ML];
queue< Trie* > Q;
Trie *Word[MN],*R = new Trie(),*aux;

void Add(Trie *Node,char *P,int Idx)
{
    if (*P == 0)
    {
        Word[Idx] = Node;
        return;
    }

    if (Node->Sons[*P - 'a'] == 0)
        Node->Sons[*P - 'a'] = new Trie();

    Add(Node->Sons[*P - 'a'],P + 1,Idx);
}

void DFS(Trie* Node)
{
    for (auto aux : Node->V)
    {
        DFS(aux);
        Node->Nr += aux->Nr ;
    }
}

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

    fin >> A >> N;

    for (int i = 1;i <= N;i++)
    {
        fin >> B;
        Add(R,B,i);
    }

    fin.close();

    Q.push(R);

    while (!Q.empty())
    {
        Trie *Node = Q.front();

        for (int i = 0;i < 26;i++)
            if (Node->Sons[i])
            {
                aux = Node->Sfx;

                while (aux != 0 && aux->Sons[i] == 0)
                      aux = aux->Sfx;

                if (aux == 0)
                {
                    Node->Sons[i]->Sfx = R;
                    R->V.push_back(Node->Sons[i]);
                }
               else
                {
                    Node->Sons[i]->Sfx = aux->Sons[i];
                    aux->Sons[i]->V.push_back(Node->Sons[i]);
                }

                Q.push(Node->Sons[i]);
            }

            Q.pop();
    }

    aux = R;

    for (int i = 0;i < strlen(A);i++)
    {
        while (aux != 0 && aux->Sons[A[i] - 'a'] == 0)
              aux = aux->Sfx;

        if (aux == 0)
           aux = R;
      else
           aux = aux->Sons[A[i] - 'a'];

        aux->Nr++;
    }

    DFS(R);

    for (int i = 1;i <= N;i++)
        fout << Word[i]->Nr << "\n";

    fout.close();

  return 0;
}