Cod sursa(job #1377382)

Utilizator sebinechitasebi nechita sebinechita Data 5 martie 2015 21:27:59
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.26 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <cstring>
using namespace std;
ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");
#define MAX 10005
int dr, dr1, st;
char a[100 * MAX], b[MAX];
int  rez[101];


struct ac{
    vector<int> v;
    int val;
    int nr;
    ac* fiu[26];
    ac* fail;
    ac(){
        nr = ++dr1;
        val = 0;
        memset(fiu, 0, sizeof(fiu));
    }
} *R, *Q[100 * MAX];

void ins(ac *nod, char *a, int ind)
{
    if(!a[0])
    {
        nod->v.push_back(ind);
        return;
    }
    if(!nod->fiu[a[0] - 'a'])
        nod->fiu[a[0] - 'a'] = new ac();
    ins(nod->fiu[a[0] - 'a'], a + 1, ind);
}

void bfs(ac *nod){
    ac *f;
    nod->fail = nod;
    st = dr = 1;
    Q[st] = nod;
    while(st <= dr)
    {
        nod = Q[st++];
        for(int i = 0 ; i < 26 ; i++)
        {
            if(nod->fiu[i] == 0)
                continue;
            f = nod->fail;
            while(f != R && !f->fiu[i]){
                f = f->fail;
            }
            if(f->fiu[i] && f->fiu[i] != nod->fiu[i])
                f = f->fiu[i];
            nod->fiu[i]->fail = f;
            Q[++dr] = nod->fiu[i];
        }
    }
}

void af(ac *nod)
{
    cout << nod->nr << " " << nod->val << "\n";
    for(int i = 0 ; i < 26 ; i++)
    {
        if(nod->fiu[i])
        {
            af(nod->fiu[i]);
        }
    }
}

void compute()
{
    ac* nod = R;
    for(int i = 0 ; a[i] ; i++)
    {
        while(nod != R && !nod->fiu[a[i] - 'a'])
            nod = nod->fail;
        if(nod->fiu[a[i] - 'a'])
            nod = nod->fiu[a[i] - 'a'];
        nod->val++;
    }
}

void anti_bfs()
{
    ac *nod;
    for(int i = dr ; i >= 1 ; i--)
    {
        nod = Q[i];
        nod->fail->val+=nod->val;
        for(vector<int>::iterator it = nod->v.begin() ; it != nod->v.end() ; it++)
        {
            rez[*it] = nod->val;
        }
    }
}

int main()
{
    int n, i;
    R = new ac();
    fin >> a;
    fin >> n;
    for(i = 1 ; i <= n ; i++)
    {

        fin >> b;
        ins(R, b, i);
    }

    bfs(R);
    compute();
   // af(R);
    anti_bfs();
    for(i = 1 ; i <= n ; i++)
    {
        fout << rez[i] << "\n";
    }
}