Cod sursa(job #2763817)

Utilizator DragosC1Dragos DragosC1 Data 16 iulie 2021 21:37:45
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.37 kb
#include <fstream>
#include <cstring>
#include <vector>
#include <iostream>
using namespace std;
 
struct aho_corasick {
    int nr;
    vector<int> cuv;
    aho_corasick* fail;
    aho_corasick* lit[26];
    aho_corasick() {
        nr = 0;
        fail = 0;
        for (int i = 0; i < 26; i++)
            lit[i] = 0;
    }
};

char s[1000001];
int n;
int rez[101];

aho_corasick *root = new aho_corasick();

void insert(aho_corasick *nod, char sir[], int ind) {
    if (*sir == 0)
        nod->cuv.push_back(ind);
    else {
        int l = *sir - 'a';
        if (nod->lit[l] == 0)
            nod->lit[l] = new aho_corasick();
        insert(nod->lit[l], sir + 1, ind);
    }
}

void read() {
    char aux[10001];
    ifstream f("ahocorasick.in");
    f >> s;
    f >> n;
    for (int i = 1; i <= n; i++) {
        f >> aux;
        insert(root, aux, i);
    }
}

aho_corasick *Q[100 * 100 + 1];
int st, dr;

void bfs() {
    int i;
    aho_corasick *aux, *cur;
    root->fail = root;
    st = 1, dr = 0;
    Q[++dr] = root;
    while (st <= dr) {
        cur = Q[st], st++;
        for (i = 0; i < 26; i++)
            if (cur->lit[i] != 0) {
                aux = cur->fail;
                while (aux->lit[i] == 0 && aux != root)
                    aux = aux->fail;
                if (aux->lit[i] != 0 && aux->lit[i] != cur->lit[i])
                    aux = aux->lit[i];
                cur->lit[i]->fail = aux;
                Q[++dr] = cur->lit[i];
            }
    }
    root->fail = 0;
}

void anti_bfs() {
    int i, j;
    aho_corasick *cur;
    for (i = dr; i >= 1; i--) {
        cur = Q[i];
        if (cur->fail != 0) 
            cur->fail->nr += cur->nr;
        for (j = 0; j < cur->cuv.size(); j++)
            rez[cur->cuv[j]] = cur->nr;  
    }
}

void solve() {
    int i, lung = strlen(s), l;
    bfs();
    aho_corasick *aux = root;
    for (i = 0; i < lung; i++) {
        l = s[i] - 'a';
        while (aux->lit[l] == 0 && aux != root)
            aux = aux->fail;
        if (aux->lit[l] != 0)
            aux = aux->lit[l];
        aux->nr++;
    }
    anti_bfs();
}

void output() {
    int i;
    ofstream g("ahocorasick.out");
    for (i = 1; i <= n; i++)
        g << rez[i] << '\n';
    g.close();
}
 
int main() {
    read();
    solve();
    output();
    return 0;
}