Cod sursa(job #764313)

Utilizator test666013Testez test666013 Data 4 iulie 2012 18:32:32
Problema Aho-Corasick Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.82 kb
#include <cstdio>
#include <vector>
using namespace std;
#define MAXA 1000001
#define MAXB 10001

struct dict{
    struct dict *f[26];
    struct dict *fail;
    vector<int>cuv;
    int nr; // nr de aparitii
}*t,*c[2*MAXA];

char a[MAXA],b[MAXB];
int n,num[101],u;

void adauga(char *b,int k){
    dict *g = t;
    int urm;
    while('a' <= *b && *b <= 'z')
    {
        urm = *b - 'a';
        if( g->f[urm] == NULL )g->f[urm] = new dict;
        g = g->f[urm];
        b++;
    }
        g->cuv.push_back(k); // introducem cuvintul dat
}

void bfs(){
    dict *fr = t, *dir;
    int p;
    t->fail = t;
    c[p = u = 1] = t;
    while(p <= u)
    {
        fr = c[p++];
        for(int i=0;i<26;i++)
        if(fr->f[i] != NULL)
        {
            for(dir = fr->fail; dir != t && dir->f[i] == NULL;dir = dir->fail);
            if(fr->f[i] != dir->f[i])dir = dir->f[i];
            fr->f[i]->fail = dir;
            c[++u] = fr->f[i];
        }
    }
    t->fail = NULL;
}

void ahocorasick(char *b){
    dict *g = t;
    int urm;
    while('a' <= *b && *b <= 'z')
    {
        urm = *b - 'a';
        for(;g != t && g->f[urm] == NULL;g = g->fail);
        if(g->f[urm] != NULL)g = g->f[urm];
        g->nr++;
        b++;
    }
}

void antibfs(){
    dict *fr;
    while(u > 0)
    {
        fr = c[u--];
        if(fr->fail != NULL)fr->fail->nr += fr->nr;
        for(int i=0;i<fr->cuv.size();i++)num[ fr->cuv[i] ] = fr->nr;
    }
}

int main(){
    freopen("ahocorasick.in","r",stdin);
    freopen("ahocorasick.out","w",stdout);
    t = new dict; // cream dictionarul
        scanf("%s ",a);
        scanf("%d ",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%s ",b);
            adauga(b,i); // introduce in structura
        }
    bfs();
    ahocorasick(a);
    antibfs();
    for(int i=1;i<=n;i++)printf("%d\n",num[i]);
    return 0;
}