Cod sursa(job #2763806)

Utilizator DragosC1Dragos DragosC1 Data 16 iulie 2021 21:01:49
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.39 kb
#include <fstream>
#include <cstring>
#include <vector>
#include <iostream>
using namespace std;

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

struct aho_cosarick {
    vector<int> nod_cuvant;
    int nr;
    aho_cosarick* lit[26];
    aho_cosarick* fail;
    aho_cosarick() {
        nr = 0;
        fail = 0;
        for (int i = 0; i < 26; i++)
            lit[i] = 0;
    }
};

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

aho_cosarick* root = new aho_cosarick();

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);
    }
}

int st, dr;

aho_cosarick *Q[100 * 100 + 1];

void bfs() {
    int i;
    aho_cosarick *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 != root && aux->lit[i] == 0)
                    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_cosarick* cur;
    for (i = dr; i >= 1; i--) {
        cur = Q[i];
        if (cur->fail != 0)
            cur->fail->nr += cur->nr;
        for (j = 0; j < cur->nod_cuvant.size(); j++)
            rez[cur->nod_cuvant[j]] = cur->nr;
    }
}

void solve() {
    int l = strlen(s), i;
    bfs();
    aho_cosarick* aux = root;
    for (i = 0; i < l; i++) {
        while (aux->lit[s[i] - 'a'] == 0 && aux != root)
            aux = aux->fail;
        if (aux->lit[s[i] - 'a'] != 0)
            aux = aux->lit[s[i] - 'a'];
        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;
}