Cod sursa(job #3250406)

Utilizator MikeStrikeAgache Mihai MikeStrike Data 20 octombrie 2024 17:48:13
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.14 kb
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
#include <fstream>

using namespace std;

struct TrieNode {
    vector<int> output;
    TrieNode *children[26]; 
    TrieNode *failure; 

    TrieNode() {
        memset(children, 0, sizeof(children));
        failure = nullptr;
    }
};

class AhoCorasick {
private:
    TrieNode *root;
    vector<string> words;

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

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

 
    void build() {
        queue<TrieNode*> q;
        root->failure = root; 

        for (int i = 0; i < 26; i++) {
            if (root->children[i]) {
                root->children[i]->failure = root;
                q.push(root->children[i]);
            } else {
                root->children[i] = root; 
            }
        }

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

            for (int i = 0; i < 26; i++) {
                if (current->children[i]) {
                    TrieNode *failureNode = current->failure;

                    while (failureNode->children[i] == nullptr) {
                        failureNode = failureNode->failure;
                    }
                    current->children[i]->failure = failureNode->children[i];

                    current->children[i]->output.insert(current->children[i]->output.end(),
                                                        failureNode->children[i]->output.begin(),
                                                        failureNode->children[i]->output.end());

                    q.push(current->children[i]);
                }
            }
        }
    }


    vector<int> search(const string &text) {
        vector<int> occurrences(words.size(), 0);
        TrieNode *current = root;

        for (char c : text) {
            int idx = c - 'a';


            while (current->children[idx] == nullptr) {
                current = current->failure;
            }
            current = current->children[idx];

        
            for (int index : current->output) {
                occurrences[index]++;
            }
        }

        return occurrences;
    }

    void addWord(const string &word) {
        words.push_back(word);
        insert(word, words.size() - 1);
    }
};

int main() {
    ifstream fin("ahocorasick.in");
    ofstream fout("ahocorasick.out");

    string A;
    fin >> A; 
    int n;
    fin >> n; 


    AhoCorasick ac;
    
    for (int i = 0; i < n; i++) {
        string word;
        fin>>word;
        ac.addWord(word);
    }

    ac.build(); 
    vector<int> occurrences = ac.search(A);

    for (int count : occurrences) {
        fout << count << endl; 
    }

    return 0;
}