Cod sursa(job #853957)

Utilizator dicu_dariaDaria Dicu dicu_daria Data 12 ianuarie 2013 16:40:41
Problema Aho-Corasick Scor 95
Compilator cpp Status done
Runda Arhiva educationala Marime 1.75 kb
#include <fstream>
#include <queue>
#include <cstring>
#include <vector>
using namespace std;

struct Trie
{
    Trie *fii[26];
    Trie *fail;
    vector<int>pattern;
    Trie()
    {
        memset(fii, 0, sizeof(fii));
    }
};

queue<Trie*>Q;
string s, p;
int k, i, j, t, sol[200];
Trie *T = new Trie;

void insert(Trie *nod)
{
    if(nod->fii[p[k]-'a'] == 0)
        nod->fii[p[k]-'a'] = new Trie;
    k++;
    if(p[k] == '\n')
    {
        nod->fii[p[k-1]-'a']->pattern.push_back(i);
        return;
    }
    insert(nod->fii[p[k-1]-'a']);
}

int main()
{
    Trie *nod, *x, *y, *z;
    ifstream fi("ahocorasick.in");
    ofstream fo("ahocorasick.out");
    fi >> s >> t;
    s = s + "\n";
    for(i = 1; i <= t; i++)
    {
        fi >> p;
        p = p + "\n";
        nod = T;
        k = 0;
        insert(nod);
    }
    for(i = 0; i < 26; i++)
    if(T->fii[i] != 0)
    {
        T->fii[i]->fail = T;
        Q.push(T->fii[i]);
    }
    while(!Q.empty())
    {
        x = Q.front(); Q.pop();
        for(i = 0; i < 26; i++)
        {
            if(x->fii[i] == 0) continue;
            Q.push(x->fii[i]);
            y = x->fii[i];
            z = x->fail;
            while(z != T and z->fii[i] == 0) z = z->fail;
            if(z->fii[i] == 0) y->fail = T; else
            y->fail = z->fii[i];
            for(j = 0; j < y->fail->pattern.size(); j++)
                y->pattern.push_back(y->fail->pattern[j]);
        }
    }
    nod = T;
    k = 0;
    while(s[k] != '\n')
    {
        while(nod != T and nod->fii[s[k]-'a'] == 0) nod = nod->fail;
        if(nod->fii[s[k]-'a'] != 0) nod = nod->fii[s[k]-'a'];
        for(i = 0; i < nod->pattern.size(); i++) sol[nod->pattern[i]]++;
        k++;
    }
    for(i = 1; i <= t; i++) fo << sol[i] << "\n";
    return 0;
}