Cod sursa(job #2148012)

Utilizator FlorinHajaFlorin Gabriel Haja FlorinHaja Data 1 martie 2018 14:14:31
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.05 kb
#include <fstream>
#include <cstring>
#include <vector>

using namespace std;

ifstream f("ahocorasick.in");
ofstream g("ahocorasick.out");

struct trie {
    trie *fail, *urm[28];
    vector<int> ind_sol;
    int cnt;
    trie() {
        fail = 0;
        cnt = 0;
        memset(urm, 0, sizeof(urm));
    }
};
trie *inc = new trie, *coada[1000005];
int st, dr, n, m, i, j, sol[105];
char s[1000005], s2[10000];

void add(trie *t, char *s, int ind) {
    while (*s >='a') {
        if (t -> urm[*s-'a'] == 0)
            t -> urm[*s-'a'] = new trie;
        t = t -> urm[*s-'a'];
        s++;
    }
    t -> ind_sol.push_back(ind);
}

void bfs() {
    trie *x, *y, *d;
    int i, l;
    inc -> fail = inc; // evitam KBS 11 la BFS, cand initializam variabila d
    coada[0] = inc;
    while (st <= dr) {
        x = coada[st++];
        for (i = 0; i < 26; i++) {
            if (x -> urm[i] == 0) continue;
            y = x -> urm[i];
            d = x -> fail;

            while (d != inc && d -> urm[i] == 0) d = d -> fail;
            if (d -> urm[i] != NULL && d -> urm[i] != y)
                d = d -> urm[i];

            x -> urm[i] -> fail = d;
            coada[++dr] = y;
        }
    }
    inc -> fail = 0;
}

void kmp_impostor() {
    int i, ind;
    trie *x = inc;
    for (i = 1; i <= n; i++) {
        ind = s[i]-'a';
        while (x != inc && x -> urm[ind] == 0) x = x -> fail;
        if (x -> urm[ind] != 0) x = x -> urm[ind];
        x -> cnt++;
    }
}

void bfs_inv() {
    int i, j;
    trie *x;
    for (i = dr; i >= 0; i--) {
        x = coada[i];
        if (x -> fail != 0)
            x -> fail -> cnt += x -> cnt;
        for (j = 0; j < x -> ind_sol.size(); j++)
            sol[ x->ind_sol[j] ] = x -> cnt;
    }
}

int main() {

    f >> s+1 >> m;
    n = strlen(s+1);
    for (i = 1; i <= m; i++) {
        f >> s2+1;
        add(inc, s2+1, i);
    }
    bfs();
    kmp_impostor();
    bfs_inv();
    for (i = 1; i <= m; i++)
        g << sol[i] << '\n';
    return 0;
}