Cod sursa(job #2440235)

Utilizator MortemPlaiasu Iulia-Silvia Mortem Data 17 iulie 2019 23:57:16
Problema Aho-Corasick Scor 25
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.1 kb
#include <iostream>
#include <fstream>
#include <queue>
#include <list>
#include <vector>
using namespace std;

ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");

struct nod
{
  int cnt;
  std::vector<int> id;
  nod* back;
  nod* son['z'-'a'+1]={0};
};

char c[1005000];
char v[150][10500];
int countt[150];
nod * root;
std::queue<nod *> q;
int n,l;
char clear[10];
std::list<int> s;
std::vector<nod *> termNode;

int main()
{
  fin.getline(c,1005000);
  fin>>n;
  fin.getline(clear,10);
  root= new nod;
  root->back= root;
  for(int i=0;i<n;i++)
  {
    fin.getline(v[i],10500);
    nod * nd= root;
    for(int j=0;v[i][j]!='\0';j++)
    {
      int ch= v[i][j]-'a';
      if(nd->son[ch]==0)
        nd->son[ch]=new nod;
      if(nd==root)
        nd->son[ch]->back=root;
      nd= nd->son[ch];
      if(v[i][j+1]=='\0')
        nd->id.push_back(i);
    }
  }
  for(int i=0;i<='z'-'a';i++)
    if(root->son[i]!=0)
    {
      q.push(root->son[i]);
      termNode.push_back(root->son[i]);
    }
  while(!q.empty())
  {
    nod * tp= q.front();
    q.pop();
    for(int i=0;i<='z'-'a';i++)
    {
      nod * u = tp->son[i];
      if(u!=0)
      {
        q.push(u);
        if(u->id.size()!=0)
          termNode.push_back(u);
        nod * nd= tp->back;
        while( nd!=root &&nd->son[i]==0)
          nd= nd->back;
        if(nd->son[i]==0)
        {
          u->back=root;
          continue;
        }
        u->back= nd->son[i];
      //  s = u->back->id;
        if(u->id.size()==0)
          u->id=u->back->id;
        else if(u->id.size()!=0 &&u->back->id.size()!=0)
          u->id.insert(u->id.end(),u->back->id.begin(),u->back->id.end());
      //  u->back->id=s;
      }
    }
  }
  nod * nd= root;
  for(int i=0;c[i]!='\0';i++)
  {
    int ch = c[i]-'a';
    while(nd->son[ch]==0 && nd!=root) nd= nd->back;
    if(nd->son[ch]==0) continue;
    nd->son[ch]->cnt++;
    nd=nd->son[ch];
  }//*/
  for(int i=termNode.size()-1;i>=0;i--)
  {
    nod * u =termNode[i];
    for(int it= 0;it!=u->id.size();++it )
      countt[u->id[it]]+=u->cnt;
  //  u->back->cnt+=u->cnt;
  }
  for(int i=0;i<n;i++)
    fout<<countt[i]<<"\n";
}