Cod sursa(job #758481)

Utilizator SpiderManSimoiu Robert SpiderMan Data 15 iunie 2012 19:54:49
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.26 kb
# include <cstdio>
# include <cstring>
# include <vector>
using namespace std;

const char *FIN = "ahocorasick.in", *FOU = "ahocorasick.out";
const int MAX_N = 105, MAX_S = 1000005, MAX_C = 10005, SG = 26;

struct AC {
    AC *fiu[SG], *fail;
    vector <int> vec;
    int number;
    AC () {
        number = 0;
        fail = NULL;
        memset (fiu, 0, sizeof (fiu));
    }
};

int M, solution[MAX_N];
char sir[MAX_S], chr[MAX_C];
vector < AC* > Q;
AC *trie, *T;

inline int getit (char ch) {
    return ch - 'a';
}

void insert (AC *trie, char *ch, int val) {
    if (*ch == '\0') {
        trie -> vec.push_back (val);
        return ;
    }
    int value = getit (*ch);
    if (trie -> fiu[value] == 0) trie -> fiu[value] = new AC;
    insert (trie -> fiu[value], ch + 1, val);
}

void bfs (AC *trie) {
    trie -> fail = trie;
    Q.push_back (trie);
    for (size_t i = 0; i < Q.size (); ++i) {
        AC *act = Q[i], *aux;
        for (int i = 0; i < SG; ++i) {
            if (act -> fiu[i] == NULL) continue;
            for (aux = act -> fail; aux != trie && aux -> fiu[i] == NULL; aux = aux -> fail);
            if (aux -> fiu[i] != NULL && aux -> fiu[i] != act -> fiu[i]) aux = aux -> fiu[i];
            act -> fiu[i] -> fail = aux, Q.push_back (act -> fiu[i]);
        }
    }
    trie -> fail = NULL;
}

void reversebfs (AC *trie) {
    for (int i = Q.size () - 1; i + 1; --i) {
        AC *act = Q[i];
        if (act -> fail != NULL) act -> fail -> number += act -> number;
        for (vector <int> :: iterator it = act -> vec.begin (); it != act -> vec.end (); ++it)
            solution[*it] = act -> number;
    }
}

int main (void) {
    freopen (FIN, "r", stdin);
    freopen (FOU, "w", stdout);

    scanf ("%s %d", sir, &M);
    trie = new AC;
    for (int i = 1; i <= M; ++i) {
        scanf ("%s", chr);
        insert (trie, chr, i);
    }
    bfs (trie), T = trie;
    for (int i = 0, j = strlen (sir), value; i < j; ++i) {
        for (value = getit (sir[i]); T -> fiu[value] == NULL && T != trie; T = T -> fail);
        if (T -> fiu[value] != NULL) T = T -> fiu[value];
        T -> number += 1;
    }
    reversebfs (trie);
    for (int i = 1; i <= M; ++i)
        printf ("%d\n", solution[i]);
}