Cod sursa(job #1081468)

Utilizator oprea1si2si3Oprea Sebastian oprea1si2si3 Data 13 ianuarie 2014 17:32:19
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.82 kb
#include<fstream>
#include<vector>
#define NMAX 1000100
#define NMAx 10010
#define CH(x) x-'a'
using namespace std;
char s[NMAX],a[NMAx];
int n,nrc,v[NMAx],SOL[NMAx];
vector <int> sol[NMAx];

struct Trie{int inf;
            Trie *fiu[26],*fail;
            Trie() {
                inf=0;
                fail=0;
                for(int i=0;i<26;i++)
                    fiu[i]=0;
                }
            };
Trie *T=new Trie;
Trie *deque[NMAX];

void solve() {
    int i;
    Trie *nod=T;
    for(i=0;s[i];i++) {
        while(!nod->fiu[CH(s[i])]&&nod!=T)
            nod=nod->fail;
        if(nod->fiu[CH(s[i])])
            nod=nod->fiu[CH(s[i])];
        if(nod->inf)
            v[nod->inf]++;
        }
}
void fail() {
    int i,j,nr=0;
    Trie *nod,*p;
    for(i=0;i<26;i++)
        if(T->fiu[i]) {
            T->fiu[i]->fail=T;
            deque[nr++]=T->fiu[i];
            }
    for(i=0;i<nr;i++) {
        nod=deque[i];
        for(j=0;j<26;j++) {
            p=nod;
            if(nod->fiu[j]) {
                while(p!=T) {
                    if(p->fail->fiu[j]) {
                        nod->fiu[j]->fail=p->fail->fiu[j];
                        break;
                        }
                    else
                        p=p->fail;
                    }
                p=nod->fiu[j];
                if(p->fail==0)
                    p->fail=T;
                deque[nr++]=p;
                if(p->fail->inf) {
                    if(!p->inf) {
                        p->inf=++nrc;
                        sol[nrc].insert(sol[nrc].end(),sol[p->fail->inf].begin(),sol[p->fail->inf].end());
                        }
                    else
                        sol[p->inf].insert(sol[p->inf].begin(),sol[p->fail->inf].begin(),sol[p->fail->inf].end());
                    }
                }
            }
        }
}
void citire() {
    int i,j;
    Trie *nod;
    ifstream in("ahocorasick.in");
    in.getline(s,NMAX-2);
    in>>n;
    in.getline(a,2);
    for(i=0;i<n;i++) {
        in.getline(a,NMAx);
        nod=T;
        for(j=0;a[j];j++) {
            if(nod->fiu[CH(a[j])]==0)
                nod->fiu[CH(a[j])]=new Trie;
            nod=nod->fiu[CH(a[j])];
            }
        ++nrc;
        if(nod->inf==0) {
            nod->inf=nrc;
            sol[nrc].push_back(nrc);
            }
        else
            sol[nod->inf].push_back(nrc);
        }
    in.close();
}
void afis() {
    int i,j;
    ofstream out("ahocorasick.out");
    for(i=1;i<=nrc;i++)
        if(v[i])  {
            for(j=0;j<sol[i].size();j++)
                SOL[sol[i][j]]+=v[i];
            }
    for(i=1;i<=n;i++)
        out<<SOL[i]<<'\n';
    out.close();
}
int main() {
    citire();
    fail();
    solve();
    afis();
    return 0;
}