Cod sursa(job #3242744)

Utilizator Her0ninjaDragos Rolland Her0ninja Data 13 septembrie 2024 22:20:44
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.87 kb
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
#include <fstream>
using namespace std;

const int abece = 26;

struct TrieNode {
    TrieNode* gyerek[abece];
    TrieNode* hiba;
    vector<int> vege;

    TrieNode() {
        memset(gyerek, 0, sizeof(gyerek));
        hiba = nullptr;
    }
};

class AhoCorasick {
    TrieNode* root;

public:
    AhoCorasick() {
        root = new TrieNode();
    }

    void insert(const string& word, int index) {
        TrieNode* node = root;
        for (char c : word) {
            int idx = c - 'a';
            if (node->gyerek[idx] == nullptr) {
                node->gyerek[idx] = new TrieNode();
            }
            node = node->gyerek[idx];
        }
        node->vege.push_back(index);
    }

    void buildhiba() {
        queue<TrieNode*> q;
        root->hiba = root;

        for (int i = 0; i < abece; ++i) {
            if (root->gyerek[i]) {
                root->gyerek[i]->hiba = root;
                q.push(root->gyerek[i]);
            } else {
                root->gyerek[i] = root;
            }
        }

        while (!q.empty()) {
            TrieNode* curr = q.front();
            q.pop();

            for (int i = 0; i < abece; ++i) {
                if (curr->gyerek[i]) {
                    TrieNode* failure = curr->hiba;
                    while (!failure->gyerek[i]) {
                        failure = failure->hiba;
                    }
                    curr->gyerek[i]->hiba = failure->gyerek[i];
                    curr->gyerek[i]->vege.insert(
                        curr->gyerek[i]->vege.end(),
                        failure->gyerek[i]->vege.begin(),
                        failure->gyerek[i]->vege.end()
                    );
                    q.push(curr->gyerek[i]);
                }
            }
        }
    }

    vector<int> search(const string& text, int numszo) {
        vector<int> valasz(numszo,0);
        TrieNode* node = root;

        for (char c : text) {
            int idx = c - 'a';
            while (!node->gyerek[idx]) {
                node = node->hiba;
            }
            node = node->gyerek[idx];

            for (int szoIndex : node->vege) {
                valasz[szoIndex]++;
            }
        }

        return valasz;
    }
};

int main() {
    ifstream f("ahocorasick.in");
    ofstream g("ahocorasick.out");

    string text;
    int n;
    f >> text;
    f >> n;

    vector<string> szotar(n);
    for (int i = 0; i < n; ++i) {
        f >> szotar[i];
    }

    f.close();

    AhoCorasick ac;
    for (int i = 0; i < n; ++i) {
        ac.insert(szotar[i], i);
    }

    ac.buildhiba();

    vector<int> jelen = ac.search(text, n);

    for (int count : jelen) {
        g << count << endl;
    }

    g.close();

    return 0;
}