Cod sursa(job #2499389)

Utilizator mihneacazCazacu Mihnea mihneacaz Data 26 noiembrie 2019 00:10:16
Problema Aho-Corasick Scor 5
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.44 kb
#include <fstream>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <stack>

using namespace std;

ifstream cin ("ahocorasick.in");
ofstream cout ("ahocorasick.out");
struct TRIE
{
    int frecv;
    TRIE *next[26];
    TRIE *link;
    TRIE()
    {
        frecv = 0;
        link = nullptr;
        memset(next, 0, sizeof(next));
    }
};

TRIE *root = new TRIE();

vector <TRIE*> leafs;

void insert_letter(TRIE *&node, const string &s, int poz)
{
    if(poz == s.size()) {
        leafs.push_back(node);
        return;
    }
    int next_node = s[poz] - 'a';
    if(node -> next[next_node] == nullptr) {
        node -> next[next_node] = new TRIE();
    }
    insert_letter(node -> next[next_node], s, poz + 1);
}

int main()
{
    string d;
    int n;
    cin>>d>>n;
    for(int i = 1; i <= n; ++i) {
        string s;
        cin>>s;
        insert_letter(root, s, 0);
    }
    queue <TRIE*> q;
    stack <TRIE*> st;
    q.push(root);
    while(!q.empty()) {
        auto a = q.front();
        st.push(a);
        q.pop();
        for(int i = 0; i < 26; ++i) {
            if(a -> next[i] != nullptr) {
                auto aux = a;
                while(aux != nullptr && aux -> link != nullptr && aux -> link -> next[i] != nullptr) {
                    aux = aux -> link;
                }
                if(aux == nullptr)
                    aux = root;
                if(aux == root) {
                    if(a != root && root -> next[i] != nullptr)
                        a -> next[i] -> link = root -> next[i];
                    else
                        a -> next[i] -> link = root;
                }
                else
                    a -> next[i] -> link = aux;
                q.push(a -> next[i]);
            }
        }
    }
    auto curr = root;
    for(int i = 0; i < d.size(); ++i) {
        if(curr == nullptr)
            curr = root;
        while(curr != root && curr != nullptr && curr -> next[d[i] - 'a'] == nullptr)
            curr = curr -> link;
        if(curr != nullptr)
            curr = curr -> next[d[i] - 'a'];
        if(curr != nullptr)
            curr -> frecv += 1;
    }
    while(st.size()) {
        auto vf = st.top();
        st.pop();
        if(vf -> link != nullptr)
            vf -> link -> frecv += vf -> frecv;
    }
    for(auto x: leafs)
        cout<<x -> frecv<<"\n";
    return 0;
}