Cod sursa(job #2243466)

Utilizator ctlin04UAIC.VlasCatalin ctlin04 Data 20 septembrie 2018 17:09:25
Problema Aho-Corasick Scor 15
Compilator cpp Status done
Runda Arhiva educationala Marime 2.02 kb
#include<iostream>
#include<fstream>
#include<string>
#include<vector>
#include<cstring>
using namespace std;

struct trie {
   vector<int> words;
   trie *next[27], *error;
   int count;
   
   trie () {
   	  count = 0;
      words.clear();
      memset(next,0,sizeof(next));
   }
};

trie *root = new trie();
int n, sol[105];
string a, w;
vector<trie *> bfs_order;

void insert(string w, int idx) {
  
   trie *aux = root;
   
   for (int i=0; i<w.length(); ++i) {
      if (aux->next[w[i]-'a']==0) aux->next[w[i]-'a']=new trie();
      aux = aux->next[w[i]-'a'];
   }
   
   aux->words.push_back(idx);
	
}

void build_error_links(trie *aux) {
   
    for (int i=0; i<=26; ++i)
	 if (aux->next[i]!=0) {
	      trie *start = aux->error;
	      while (start!=root && start->next[i]==0) start = start->error;
	      
	      if (aux!=root && start->next[i]!=0) aux->next[i]->error = start->next[i];
	      else aux->next[i]->error = root;
	      
	      build_error_links(aux->next[i]);
     }
 	
}

void propagate_counts(trie *aux) {
  
  bfs_order.clear();
  bfs_order.push_back(aux);
  
  for (int i=0; i<bfs_order.size(); ++i)
   for (int j=0; j<=26; ++j) 
    if (bfs_order[i]->next[j]!=0) bfs_order.push_back(bfs_order[i]->next[j]);
    
  for (int i=bfs_order.size()-1; i>=0; --i) {
     aux = bfs_order[i];	
   	
   	 aux->error->count += aux->count;
   	 for (int j=0; j<aux->words.size(); ++j)
   	  sol[aux->words[j]]=aux->count;
  }
	
}

int main(void) {
	ifstream cin("ahocorasick.in");
	ofstream cout("ahocorasick.out");
	
	cin>>a>>n;
	
	for (int i=1; i<=n; ++i) {
	   cin>>w;
	   insert(w, i);	
	}
	
	root->error = root;
	build_error_links(root);
	
	trie *aux = root;
	
	for (int i=0; i<a.length(); ++i) {
		
	   while (aux->next[a[i]-'a']==0 && aux!=root) aux = aux->error;
	   if (aux->next[a[i]-'a']!=0) aux = aux->next[a[i]-'a'];	
		
	   ++aux->count;
	}
	
	propagate_counts(root);
	
	for (int i=1; i<=n; ++i) cout<<sol[i]<<"\n";
	
  return 0;	
}