Cod sursa(job #2543270)

Utilizator bleo16783FMI Bleotiu Cristian bleo16783 Data 10 februarie 2020 23:16:26
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.27 kb
#include <fstream>
#include <vector>
#include <queue>

using namespace std;
#define SIGMA 26
#define N 128

struct trie {
    vector <int> index;
    trie *v[SIGMA];
    trie *fail;
    trie(){
        fail = NULL;
        for (int _it = 0; _it < SIGMA; ++_it)
            v[_it] = NULL;
    }
}*root, *curr, *failed;

void add (string S, int index){
    trie *node = root;
    int it = 0;
    while (it < S.size() && node->v[S[it] - 'a'] != NULL){
        node = node->v[S[it] - 'a'];
        ++it;
    }
    while (it < S.size()){
        node->v[S[it] - 'a'] = new trie();
        node = node->v[S[it] - 'a'];
        ++it;
    }
    node->index.push_back(index);
}
int i, n, j;
string dictionary[N];
string s;
queue <trie *> q;
int match[N];

int main()
{
    ifstream fin ("ahocorasick.in");
    ofstream fout ("ahocorasick.out");
    root = new trie();
    fin >> s;
    fin >> n;
    for (i = 0; i < n; ++i){
        fin >> dictionary[i];
        add (dictionary[i], i);
    }
    for (i = 0; i < SIGMA; ++i)
        if (root->v[i] != NULL){
            root->v[i]->fail = root;
            q.push(root->v[i]);
        }
    while (!q.empty()){
        curr = q.front();
        q.pop();
        for (i = 0; i < SIGMA; ++i)
        if (curr->v[i] != NULL){
            failed = curr->fail;
            while (failed != root && failed->v[i] == NULL){
                failed = failed->fail;
            }
            if (failed->v[i] != NULL){
                curr->v[i]->fail = failed->v[i];
                for (j = 0; j < failed->v[i]->index.size(); ++j){
                    curr->v[i]->index.push_back(failed->v[i]->index[j]);
                }
            }
            else{
                curr->v[i]->fail = root;
            }
            q.push(curr->v[i]);
        }
    }
    curr = root;
    for (i = 0; i < s.size(); ++i){
        while (curr != root && curr->v[s[i] - 'a'] == NULL){
            curr = curr->fail;
        }
        if (curr->v[s[i] - 'a'] != NULL){
            curr = curr->v[s[i] - 'a'];
            for (j = 0; j < curr->index.size(); ++j){
                ++match[curr->index[j]];
            }
        }
    }
    for (i = 0; i < n; ++i)
        fout << match[i] << '\n';
    return 0;
}