Cod sursa(job #2543237)

Utilizator bleo16783FMI Bleotiu Cristian bleo16783 Data 10 februarie 2020 22:50:13
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.83 kb
#include <bits/stdc++.h>

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

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];

void add_match (int id, int pos){
    ///found the id-th word from the dictionary ending at
    ///the pos-th letter of the checked string
    //match[id].push_back (pos - dictionary[id].size() + 1);
    ++match[id];
}

void find_matches (string s){
    trie *node = root;
    int it, jt;
    for (it = 0; it < s.size(); ++it){
        while (node != root && node->v[s[it] - 'a'] == NULL){
            node = node->fail;
        }
        if (node->v[s[it] - 'a'] != NULL){
            node = node->v[s[it] - 'a'];
            for (jt = 0; jt < node->index.size(); ++jt){
                add_match (node->index[jt], it);
            }
        }
    }
}

void print_matches (ostream &out){
    int it, jt;
    for (it = 0; it < n; ++it)
    /*if (match[it].size()){
        out << dictionary[it] << " : ";
        for (jt = 0; jt < match[it].size(); ++jt)
            out << match[it][jt] << " ";
        out << '\n';
    }*/
    out << match[it] << '\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]);
        }
    }
    find_matches (s);
    print_matches (fout);
    return 0;
}