Cod sursa(job #1176260)

Utilizator ctlin04UAIC.VlasCatalin ctlin04 Data 25 aprilie 2014 20:00:02
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.42 kb
#include<fstream>
#include<cstring>
#include<vector>
#include<string>
using namespace std;
typedef struct trie {
        int nr;//numarul de aparitii
        vector<int> c;//cuvintele care se termina in nodul curent
        trie *a[26], *fail;//alfabetul
        trie () {
             nr=0;
             memset(a,0,sizeof(a));
             fail=NULL;
             }
        };
trie *root, *coada[1000005];
int n,i,sol[105],lc;
string text, pattern;

void insert(string p, int ord) {
     trie *aux=root;
     for (int i=0; i<p.length(); ++i) 
      if (aux->a[p[i]-'a']!=0) aux=aux->a[p[i]-'a'];
       else {
            aux->a[p[i]-'a']=new trie;
            aux=aux->a[p[i]-'a'];
            aux->fail=aux;
            }
    aux->c.push_back(ord);
}

void buildfail(){
  int st,sf,i;
  st=sf=1;
  coada[st]=root;
  ++st;
  for (i=0; i<26; ++i) 
   if (root->a[i]!=0) {
                      root->a[i]->fail=root;
                      ++sf;
                      coada[sf]=root->a[i];
                      }   
  
  while (st<=sf) {
  
        for (i=0; i<26; ++i)
         if (coada[st]->a[i]!=0) {
                           trie *aux=coada[st]->fail;
                           while (aux!=root&&aux->a[i]==0) aux=aux->fail;
                           if (aux->a[i]!=0) coada[st]->a[i]->fail=aux->a[i];
                            else coada[st]->a[i]->fail=root;
                           ++sf;
                           coada[sf]=coada[st]->a[i];
                           }
        ++st;
      }
   lc=sf; 
}

void buildup(){
   int i,j;
   trie *aux;
   for (i=lc; i>0; --i) {
       aux=coada[i];
       aux->fail->nr+=aux->nr;
       for (j=0; j<aux->c.size(); ++j)
        sol[aux->c[j]]=aux->nr;
       }   
}

int main(void) {
    ifstream fin("ahocorasick.in");
    ofstream fout("ahocorasick.out");
    getline(fin,text);
    fin>>n; getline(fin,pattern);
    root=new trie;
    root->fail=root;
    
    for (i=1; i<=n; ++i) {
        getline(fin,pattern);
        insert(pattern,i);
        }
    
    buildfail();    
    
    trie *aux=root;
    
    for (i=0; i<text.length(); ++i) {
         int next=text[i]-'a';
         while (aux!=root&&aux->a[next]==0) aux=aux->fail;
         
         if (aux->a[next]!=0) aux=aux->a[next];
         ++aux->nr;
         }
    
    buildup();
    
    for (i=1; i<=n; ++i) fout<<sol[i]<<"\n";

  return 0;
}