Cod sursa(job #2124147)

Utilizator ValentinSavoiuFMI Savoiu Valentin-Marian ValentinSavoiu Data 6 februarie 2018 22:44:47
Problema Aho-Corasick Scor 25
Compilator cpp Status done
Runda Arhiva educationala Marime 2.05 kb
#include <fstream>
#include <vector>
#include <stack>
#include <cstring>
#include <cctype>
#define maxD 1000001
#define maxN 101
#define maxC 10000
using namespace std;
ifstream f("ahocorasick.in");
ofstream g("ahocorasick.out");
char H[maxD],s[maxC+2];
int n,Ap[maxN],i,l,r;
struct AC
{
    vector<int> Ou;
    AC *Fiu[26],*Fail;
    int n0;
    AC()
    {
        Fail=NULL;
        n0=0;
        memset(Fiu,0,sizeof(Fiu));
    }

}*t,*Q[maxN*maxN+1];

void ins(AC *node,char *p,int i)
{
    if(!isalpha(*p))
    {
        node->Ou.push_back(i);
        return ;
    }
    else
    {
        int ch=*p-'a';
        if(0==node->Fiu[ch]) node->Fiu[ch]=new AC;
        ins(node->Fiu[ch],p+1,i);
    }
}
void bfs(AC *nod)
{
    l=r=1;
    int j;
    Q[1]=nod;
    nod->Fail=nod;
    while(l<=r)
    {
        nod=Q[l];
        for(i=0;i<=25;i++)
        {
            if(nod->Fiu[i]==0) continue;
            Q[++r]=nod->Fiu[i];
            AC *f=nod->Fail;
            while(f!=t)
            {
                if(f->Fiu[i]) break;
                else f=f->Fail;
            }
            if(f->Fiu[i]&&f->Fiu[i]!=nod->Fiu[i]) nod->Fiu[i]->Fail=f->Fiu[i];
            else nod->Fiu[i]->Fail=t;
        }
        l++;
    }
}
void antibfs(AC *nod)
{
    for(int i=r;i>0;i--)
    {
        AC *nod=Q[i];
        if(nod->Fail) nod->Fail->n0+=nod->n0;
        for(int j=0;j<nod->Ou.size();j++)
            Ap[nod->Ou[j]]=nod->n0;
    }
}
int main()
{
    f>>H>>n; f.get();
    t=new AC;

    for(i=1;i<=n;i++)
    {
        f.getline(s,maxC+1);
        ins(t,s,i);
    }

    bfs(t);
    AC *nod=t,*nod2;
    i=0;
    for(i=0;i<strlen(H);i++)
    {
        int ch=H[i]-'a';
        nod2=nod;
        while(nod2!=t)
        {
            if(nod2->Fiu[ch]) break;
            nod2=nod2->Fail;
        }
        if(nod2->Fiu[ch])
        {
            nod=nod2->Fiu[ch];
            ++nod->n0;
        }
        else nod=t;
    }
    antibfs(t);
    for(i=1;i<=n;i++) g<<Ap[i]<<'\n';
    return 0;
}