Cod sursa(job #1332932)

Utilizator okros_alexandruOkros Alexandru okros_alexandru Data 2 februarie 2015 16:27:07
Problema Evaluarea unei expresii Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.73 kb
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>

#define Cmax 26
#define Nmax 105
#define Wmax 10010
#define Smax 1000100
#define ord(x) (x - 'a')
#define nextSon node->son[i]
#define nextNode node->son[ord(*p)]

using namespace std;

struct Node {
    int index;
    Node * son[Cmax], * fail;

    Node() {
        index = 0;
        fail = NULL;

        for(int i = 0 ; i < Cmax; i++)
            son[i] = NULL;
    }
};

vector <int> Solutions[Smax];
queue <Node *> Queue;
int N, visited[Smax];
char A[Smax];

class Dictionary {

    private:
        int size;
        Node * root;

    public:
        int count[Nmax];

        Dictionary() {
            size = 0;
            root = new Node;
            memset(count, 0, sizeof(count));
        }

        void insert(char * p, int & wordId) {

            Node * node = root;

            while(*p) {

                if(nextNode == NULL)
                    nextNode = new Node;

                node = nextNode;
                p++;
            }

            if(node->index == 0)
                node->index = ++size;

            Solutions[node->index].push_back(wordId);
        }

        void computeFail() {

            int i;
            Node * p, * node = root;

            node->fail = root;

            for(i = 0; i < Cmax; i++)
                if(nextSon != NULL) {
                    nextSon->fail = root;
                    Queue.push(nextSon);
                }

            while(!Queue.empty()) {

                node = Queue.front();
                Queue.pop();

                for(i = 0; i < Cmax; i++)
                    if(nextSon != NULL) {

                        p = node;
                        while(p != root && p->fail->son[i] == NULL)
                            p = p->fail;

                        if(p->fail->son[i] != NULL)
                            nextSon->fail = p->fail->son[i];
                        else
                            nextSon->fail = root;

                        Queue.push(nextSon);

                        if(nextSon->fail->index != 0) {

                            if(nextSon->index == 0)
                                nextSon->index = ++size;

                            Solutions[nextSon->index].insert(Solutions[nextSon->index].end(), Solutions[nextSon->fail->index].begin(), Solutions[nextSon->fail->index].end());
                        }
                }
            }
        }

        void search(char * p) {

            int i, j;
            Node * node = root;

            while(*p) {

                while(node != root && nextNode == NULL)
                    node = node->fail;

                if(nextNode != NULL)
                    node = nextNode;

                if(node->index != 0)
                    visited[node->index]++;

                p++;
            }

            for(i = 1; i <= size; i++)
                if(visited[i] != 0)
                    for(j = 0; j < Solutions[i].size(); j++)
                        count[Solutions[i][j]] += visited[i];

        }

} dictionary;


void Solve() {

    dictionary.computeFail();
    dictionary.search(A);
}
void Read() {

    char word[Wmax];
    ifstream in("ahocorasick.in");

    in.getline(A, Smax);
    in >> N;
    in.getline(word, Wmax);

    for(int i = 1; i <= N; i++) {
        in.getline(word, Wmax);
        dictionary.insert(word, i);
    }

    in.close();
}
void Write() {

    ofstream out("ahocorasick.out");

    for(int i = 1; i <= N; i++)
        out << dictionary.count[i] << '\n';

    out.close();
}
int main() {

    Read();
    Solve();
    Write();

    return 0;

}