Cod sursa(job #2267087)

Utilizator andrei_diaconu11Andrei C. Diaconu andrei_diaconu11 Data 23 octombrie 2018 11:03:03
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.96 kb
#include <bits/stdc++.h>

using namespace std;
const int sigma = 26;
struct trie{
  int nrf, nr;
  bool ap;
  trie *fiu[sigma], *pi, *pis;
  trie(){
    nr = nrf = 0;
    ap = false;
    memset(fiu, 0, sizeof(fiu));
    pi = pis = 0;
  }
};

trie *T = new trie;

ifstream fi("ahocorasick.in");
ofstream fo("ahocorasick.out");
string s, txt;
string::iterator frana;

trie *get_nod(trie *nod, string::iterator it){
  if(it == frana)
    return nod;
  if(nod->fiu[*it] == 0){
    nod->nrf++;
    nod->fiu[*it] = new trie;
  }
  return get_nod(nod->fiu[*it], it + 1);
}

queue <trie*> q;
vector <trie*> ord;
vector <string> dictionar;

trie *get_pi(int ch, trie *nod){
  nod = nod->pi;
  while(nod != 0 && nod->fiu[ch] == 0)
    nod = nod->pi;
  if(nod == 0)
    return T;
  return nod->fiu[ch];
}

int main()
{
  int n;
  fi >> txt >> n;
  //construim trie dictionar
  for(int i = 0; i < n; i++){
    fi >> s;
    for(int j = 0; j < s.size(); j++)
      s[j] -= 'a';
    dictionar.push_back(s);
    frana = s.end();
    get_nod(T, s.begin())->ap = true;
  }
  //construim pi pe trie cu un bfs
  q.push(T);
  while(q.size() > 0){
    trie *nod = q.front();
    ord.push_back(nod);
    q.pop();
    for(int i = 0; i < sigma; i++)
      if(nod->fiu[i] != 0){
        nod->fiu[i]->pi = get_pi(i, nod);
        if(nod->fiu[i]->pi->ap)
          nod->fiu[i]->pis = nod->fiu[i]->pi;
        else
          nod->fiu[i]->pis = nod->fiu[i]->pi->pis;
        q.push(nod->fiu[i]);
      }
  }
  //trecem la treaba
  trie *nod = T;
  for(auto ch : txt){
    ch -= 'a';
    if(nod->fiu[ch] != 0)
      nod = nod->fiu[ch];
    else
      nod = get_pi(ch, nod);
    nod->nr++;
  }
  for(int i = ord.size() - 1; i >= 0; i--)
    if(ord[i]->pis != 0)
      ord[i]->pis->nr += ord[i]->nr;
  for(auto cuv : dictionar){
    frana = cuv.end();
    fo << get_nod(T, cuv.begin())->nr << '\n';
  }
  fi.close();
  fo.close();
  return 0;
}