Cod sursa(job #767547)

Utilizator test_666013Testez test_666013 Data 13 iulie 2012 19:42:35
Problema Aho-Corasick Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 1.71 kb
#include <cstdio>
#include <cctype>
#include <vector>
using namespace std;
#define MAX 1000001

struct trie{
    struct trie *f[26];
    struct trie *fail;
    int nr;
    vector<int>cuv; }*t,*cd[MAX];

char a[MAX],b[10001];

int n,num[101],u;

void adauga(char *b,int i){
    trie *g = t;
    int urm;
    while( isalpha(*b) )
    {
        urm = *b - 'a';
        if( g->f[urm] == 0 )g->f[urm] = new trie;
        g = g->f[urm];
        b++;
    }
        g->cuv.push_back(i);
}

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

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

void antibfs(){
    trie *fr;
    while(u > 0)
    {
        fr = cd[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);
        scanf("%s ",a);
        scanf("%d ",&n);
    t = new trie;

        for(int i=1;i<=n;i++)
        {
            scanf("%s ",b);
            adauga(b,i);
        }
    bfs();
    ahocorasick(a);
    antibfs();
    for(int i=1;i<=n;i++)printf("%d\n",num[i]);
    return 0;
}