Cod sursa(job #1538083)

Utilizator DrumeaVDrumea Vasile DrumeaV Data 28 noiembrie 2015 14:31:03
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.15 kb
#include <fstream>
#include <queue>
#include <vector>
#include <string.h>

using namespace std;

const int ML = 1000006;
const int MX = 10004;
const int MN = 102;

struct Trie
{
    int nr;
    Trie *next[26],*sfx;
    vector< Trie* > V;

    Trie()
    {
        nr = 0;
        sfx = 0;
        memset(next,0,sizeof(next));
    }
};

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

void Add(Trie *Node,char *St)
{
    if (*St == 0)
    {
        Word[idx] = Node;
        return;
    }

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

    Add(Node->next[*St - 'a'],St + 1);
}

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

int main()
{
    freopen("ahocorasick.in","r",stdin);
    freopen("ahocorasick.out","w",stdout);

     scanf("%s\n%d",A,&N);

     int M = strlen(A);

     for (int i = 1;i <= N;i++)
     {
         scanf("%s\n",B);
         idx = i;
         Add(R,B);
     }

    Q.push(R);

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

        for (int i = 0;i < 26;i++)
            if (Node->next[i])
            {
                Trie *aux = Node->sfx;

                while (aux != 0 && aux->next[i] == 0)
                      aux = aux->sfx;

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

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

    Trie *aux = R;

    for (int i = 0;i < M;i++)
    {
        while (aux != 0 && aux->next[A[i] - 'a'] == 0)
              aux = aux->sfx;

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

        aux->nr++;
    }

    DFS(R);

    for (int i = 1;i <= N;i++)
        printf("%d\n",Word[i]->nr);

  return 0;
}