Cod sursa(job #952655)

Utilizator primulDarie Sergiu primul Data 23 mai 2013 19:25:13
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.97 kb
#include<fstream>
#include<vector>
#include<cstring>
#define Z s[i]-'a'
#define NMAX 10005
#define NOD Q[i-1]
using namespace std;
struct TRIE
{
    int nr;
    TRIE *fii[26],*fail;
    vector<short> nod;
    TRIE()
    {
        memset(fii,0,sizeof fii);
        nr=0;
        fail=0;
    }
}*G;
vector<TRIE*> Q;
char s[NMAX*100],cuv[NMAX];
int n,sol[105];
inline void add(char s[],short ind)
{
    TRIE *t=G;
    short i;
    for(i=0;s[i] && t->fii[Z];t=t->fii[Z],i++);
    if(!s[i])
    {
        t->nod.push_back(ind);
        return;
    }
    for(;s[i];t=t->fii[Z],i++)
        t->fii[Z]=new TRIE;
    t->nod.push_back(ind);
}
void read()
{
    ifstream fin("ahocorasick.in");
    fin>>s;
    fin>>n;
    G=new TRIE;
    for(short i=0;i<n;i++)
    {
        fin>>cuv;
        add(cuv,i);
    }
    fin.close();
}
inline void BFS()
{
    TRIE *p;
    G->fail=G;
    Q.push_back(G);
    for(size_t i=1;i<=Q.size();i++)
        for(int j=0;j<26;j++)
            if(NOD->fii[j])
            {
                for(p=NOD->fail;p!=G && !(p->fii[j]);p=p->fail);
                 
                if(p->fii[j] && p->fii[j]!=NOD->fii[j])
                    p=p->fii[j];
                NOD->fii[j]->fail=p;
                Q.push_back(NOD->fii[j]);
            }
    G->fail=0;
}
inline void BFS_back()
{
    for(size_t i=Q.size();i;i--)
    {
        if(NOD->fail)
            NOD->fail->nr+=NOD->nr;
        for(size_t j=0;j<NOD->nod.size();j++)
            sol[NOD->nod[j]]=NOD->nr;
    }
}
inline void down()
{
    TRIE *p=G;
    int l=strlen(s);
    for(int i=0;i<l;i++)
    {
        for(;!p->fii[Z] && p!=G;p=p->fail);
        if(p->fii[Z])
            p=p->fii[Z];
        p->nr++;
    }
}
void print()
{
    ofstream fout("ahocorasick.out");
    for(int i=0;i<n;i++)
        fout<<sol[i]<<'\n';
    fout.close();
}
int main()
{
    read();
    BFS();
    down();
    BFS_back();
    print();
    return 0;
}