Cod sursa(job #2590189)

Utilizator bogdi1bogdan bancuta bogdi1 Data 27 martie 2020 16:59:31
Problema Aho-Corasick Scor 100
Compilator cpp-32 Status done
Runda Arhiva educationala Marime 1.95 kb
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
struct Trie
{
    Trie(){
        counter=0;
        for(int i=0; i<26; i++)
            sons[i]=NULL;
        fail=NULL;
        adj.clear();
    }
    int counter;
    Trie *sons[26];
    Trie *fail;
    vector<Trie*> adj;
};
char s[10005];
char a[1000005];
Trie *root=new Trie;
Trie *res[105];
Trie *add(Trie *nod, char *s)
{
    if(*s==0)
        return nod;
    if(nod->sons[*s-'a']==NULL)
        nod->sons[*s-'a']=new Trie;
    return add(nod->sons[*s-'a'], s+1);
}
void bfs()
{
    queue<Trie*> q;
    q.push(root);
    while(!q.empty()){
        Trie *nod=q.front();
        q.pop();
        for(int i=0; i<26; i++){
            if(nod->sons[i]!=NULL){
                Trie *aux=nod->fail;
                while(aux && aux->sons[i]==NULL)
                    aux=aux->fail;
                if(aux==NULL)
                    aux=root;
                else
                    aux=aux->sons[i];
                nod->sons[i]->fail=aux;
                aux->adj.push_back(nod->sons[i]);
                q.push(nod->sons[i]);
            }
        }
    }
}
void dfs(Trie *nod)
{
    for(int i=0; i<nod->adj.size(); i++){
        dfs(nod->adj[i]);
        nod->counter+=nod->adj[i]->counter;
    }
}
int main()
{   freopen("ahocorasick.in", "r", stdin);
    freopen("ahocorasick.out", "w", stdout);
    int n,i,m;
    scanf("%s", a);
    m=strlen(a);
    scanf("%d\n", &n);
    for(i=1; i<=n; i++){
        scanf("%s", s);
        res[i]=add(root, s);
    }
    bfs();
    Trie *nod=root;
    for(i=0; i<m; i++){
        while(nod && nod->sons[a[i]-'a']==NULL)
            nod=nod->fail;
        if(nod==NULL)
            nod=root;
        else
            nod=nod->sons[a[i]-'a'];
        nod->counter++;
    }
    dfs(root);
    for(i=1; i<=n; i++)
        printf("%d\n", res[i]->counter);
    return 0;
}