Cod sursa(job #2221215)

Utilizator silviu982001Borsan Silviu silviu982001 Data 13 iulie 2018 14:34:35
Problema Aho-Corasick Scor 5
Compilator cpp Status done
Runda Arhiva educationala Marime 2.71 kb
#include <queue>
#include <vector>
#include <string>
#include <fstream>
#include <memory>
#include <cstdlib>

#define NMAX 26
#define MAX_WORDS 100

using namespace std;

struct Tree
{
    shared_ptr<Tree> child[NMAX];
    shared_ptr<Tree> fail;
    int counter;
    vector<int>pattern;
    Tree();
};

Tree::Tree()
{
    counter = 0;
}

queue<shared_ptr<Tree>> Q;
shared_ptr<Tree> tree;
string s, stringToFind;
int n, k, i, solution[MAX_WORDS];

bool Insert(shared_ptr<Tree>& nod)
{
    if (nod->child[stringToFind[k]-'a'] == 0)
    {
        Tree *t = new (std::nothrow) Tree;
        if (!t)
            return false;
        nod->child[stringToFind[k]-'a'] = shared_ptr<Tree>(t);
    }
    ++k;
    if (stringToFind[k] == '\n')
    {
        nod->child[stringToFind[k-1]-'a']->pattern.push_back(i);
        return true;
    }
    return Insert(nod->child[stringToFind[k-1]-'a']);
    return true;
}

void Solution(shared_ptr<Tree> nod)
{
    for (int j = 0; j < nod->pattern.size(); j++)
        solution[nod->pattern[j]] += nod->counter;
    for (int j = 0; j < NMAX; j++)
        if (nod->child[j])
            Solution(nod->child[j]);
}

int main()
{
    Tree *t = new (std::nothrow) Tree;
    if (!t)
        return EXIT_FAILURE;
    tree = shared_ptr<Tree>(t);
    shared_ptr<Tree> nod;
    ifstream fin("ahocorasick.in");
    fin >> s >> n;
    s+="\n";
    for (i = 0; i < n; i++)
    {
        fin >> stringToFind;
        stringToFind+="\n";
        nod = tree;
        k = 0;
        if (!Insert(nod))
            return EXIT_FAILURE;
    }
    fin.close();
    for (i = 0; i < NMAX; i++)
        if (tree->child[i])
        {
            tree->child[i]->fail = tree;
            Q.push(tree->child[i]);
        }
    while (!Q.empty())
    {
        shared_ptr<Tree> cNod = Q.front();
        Q.pop();
        for (i = 0; i < NMAX; i++)
        {
            if (!cNod->child[i]) continue;
            Q.push(cNod->child[i]);
            shared_ptr<Tree> cChild = cNod->child[i];
            shared_ptr<Tree> cFail = cNod->fail;
            while (!cFail->child[i]) cFail = cFail->fail;
            if (!cFail->child[i]) cChild->fail = tree;
            else cChild->fail = cFail->child[i];
            for (int j = 0; j < cChild->fail->pattern.size(); j++)
                cChild->pattern.push_back(cChild->fail->pattern[j]);
        }
    }
    nod = tree;
    k = 0;
    for (k = 0; k < s.length(); k++)
    {
        while(nod != tree && nod->child[s[k]-'a'] == 0)
            nod = nod->fail;
        if(nod->child[s[k]-'a'] != 0)
            nod = nod->child[s[k]-'a'];
        nod->counter++;
    }
    Solution(tree);
    ofstream fout("ahocorasick.out");
    for(i = 0; i < n; i++)
        fout << solution[i] << "\n";
    fout.close();
    return 0;
}