Cod sursa(job #1010504)

Utilizator deneoAdrian Craciun deneo Data 15 octombrie 2013 00:36:24
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.48 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
using namespace std;

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

const int MAXQ = 1000010;
const int MAXN = 10100;

struct Trie {
    vector<int> sir;
    int P;
    Trie *Son[26], *Fail;
    Trie() {
        P = 0;
        Fail = NULL;
        memset(Son, 0, sizeof(Son));
    }
};

int n, QL, QR, frec[MAXN];
Trie *coada[MAXQ];
string a, b;

int code (char a) {
    return (char)a - 'a';
}

void insert(Trie *A, string::iterator it, int type) {
    if (it == b.end()) {
        A->sir.push_back(type);
        return;
    }

    int cod = code(*it);
    if (A->Son[cod] == 0)
        A->Son[cod] = new Trie;


    insert (A->Son[cod], ++it, type);
}

void read(Trie *trie) {
    fin >> a; fin >> n;
    for (int i = 1; i <= n; ++i) {
        fin >> b;
        insert (trie, b.begin(), i);
    }
}

void bfs(Trie *trie) {
    trie->Fail = trie;

    QL = QR = 1;
    coada[QL] = trie;

    while (QL <= QR) {
        Trie *Node = coada[QL];
        ++QL;

        for (int i = 0; i < 26; ++i) {
            if (Node -> Son[i] == 0) continue;

            Trie *Cfail = Node->Fail;

            while (Cfail != trie && Cfail->Son[i] == 0)
                Cfail = Cfail -> Fail;
            if (Cfail->Son[i] != 0 && Cfail -> Son[i] != Node -> Son[i]) // aici mai era Cfail -> Son[i] != Node -> Son[i];
                Cfail = Cfail -> Son[i];

            Node->Son[i]->Fail = Cfail;
            coada[++QR] = Node->Son[i];
        }
    }
}

void ReverseBFS(Trie *trie) {
    while (QR > 0) {
        Trie *node = coada[QR--];

        if (node->Fail != 0)
            node->Fail->P += node->P;

        for (unsigned i = 0; i < node->sir.size(); ++i) {
            int a = node->sir[i];
            frec[node->sir[i]] += node->P;
        }
    }
}

void aho(Trie *trie) {
    bfs(trie);

    Trie *Node = trie;

    for (int i = 0; i < a.size(); ++i) {
        char c = a[i];

        while (Node->Son[code(c)] == 0 && Node != trie)
            Node = Node->Fail;
        if (Node->Son[code(c)] != 0)
            Node = Node->Son[code(c)];
        ++Node->P;
    }

    ReverseBFS(trie);
}

void print() {
    for (int i = 1; i <= n; ++i)
        fout << frec[i] << "\n";
}

Trie *trie = new Trie;

int main() {
    read(trie);
    aho(trie);
    print();
    return 0;
}