Cod sursa(job #719457)

Utilizator repp4raduRadu-Andrei Szasz repp4radu Data 21 martie 2012 20:09:23
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.12 kb
#include <fstream>
#include <vector>
#include <string.h>

#define LMAX 1000050
#define MAX 10050
#define AMAX 26

using namespace std;

struct Trie
{
    int n0;
    vector<int> cuv;
    Trie *fiu[AMAX], *fail;
    Trie()
    {
        n0 = 0; cuv.clear();
        fail = NULL;
        memset(fiu, 0, sizeof(fiu));
    }
}*t = new Trie, *q[105 * MAX], *p;
int final[105], n, i, j; char sir[LMAX], aux[MAX];

void add(Trie *t, char* sir, int poz)
{
    if(!isalpha(*sir))
    {
        t->cuv.push_back(poz);
        return;
    }
    int urm = *sir - 'a';
    if(!t->fiu[urm])
        t->fiu[urm] = new Trie;
    add(t->fiu[urm], sir + 1, poz);
}

void citire()
{
    ifstream in("ahocorasick.in");
    in.getline(sir, LMAX);
    in>>n; in.get();
    for(int i = 1; i <= n; i++)
    {
        in.getline(aux, MAX);
        add(t, aux, i);
    }
    in.close();
}

void bfs(Trie *t)
{
    Trie *f, *fr;
    t->fail = t;
    for(q[i = j = 1] = t; i <= j; i++)
    {
        fr = q[i];
        for(int h = 0; h < AMAX; h++)
            if(fr->fiu[h])
            {
                for(f = fr->fail; !f->fiu[h] && f != t; f = f->fail);
                if(f->fiu[h] && f->fiu[h] != fr->fiu[h])
                    f = f->fiu[h];
                fr->fiu[h]->fail = f;
                q[++j] = fr->fiu[h];
            }
    }
    t->fail = NULL;
}

void antibfs()
{
    for(i = j; i > 0; i--)
    {
        p = q[i];
        if(p -> fail)
            p->fail->n0 += p->n0;
        for(unsigned int h = 0; h < p->cuv.size(); h++)
            final[p->cuv[h]] = p->n0;
    }
}

void solve()
{
    bfs(t);
    int lgt = strlen(sir), urm;
    p = t;
    for(int i = 0; i < lgt; i++)
    {
        urm = sir[i] - 'a';
        for(; !p->fiu[urm] && p != t; p = p->fail);
        if(p->fiu[urm])
            p = p->fiu[urm];
        p->n0++;
    }
    antibfs();
}

void afisare()
{
    ofstream out("ahocorasick.out");
    for(int i = 1; i <= n; i++)
        out<<final[i]<<'\n';
    out.close();
}

int main()
{
    citire();
    solve();
    afisare();
    return 0;
}