Pagini recente » Cod sursa (job #1219585) | Cod sursa (job #234962) | Cod sursa (job #53710) | Cod sursa (job #528471) | Cod sursa (job #2348710)
#include <cstdio>
#include <deque>
#include <vector>
#define NRCUV 101
#define DIM_SMOL 10010
#define DIM_BIG 1000010
using namespace std;
struct trie {
int arrival;
trie *link; /// link este muchia aia care se duce in sus
vector <trie *> v;
trie *f[26];
trie (){
arrival=0;
link=0;
for (int i=0;i<26;i++)
f[i]=0;
v.clear();
}
};
trie *ending[NRCUV];
deque <trie *> dq;
char s[NRCUV][DIM_SMOL],initial[DIM_BIG];
trie *r=new trie;
trie *root=r;
trie *update (int poz,trie *&r,int i) {
if (s[poz][i]!=0){
if (r->f[s[poz][i]-'a']==NULL){
r->f[s[poz][i]-'a']=new trie;
}
return update (poz,r->f[s[poz][i]-'a'],i+1);
}
else return r;
}
void dfs (trie *nod){
int i;
for (i=0;i<nod->v.size();i++){
dfs (nod->v[i]);
nod->arrival+=nod->v[i]->arrival;
}
}
int main()
{
FILE *fin=fopen ("ahocorasick.in","r");
FILE *fout=fopen ("ahocorasick.out","w");
int n,i;
trie *nod,*ant;
fscanf (fin,"%s\n",initial);
fscanf (fin,"%d\n",&n);
/// etapa 1 : build trie
for (i=1;i<=n;i++){
fscanf (fin,"%s\n",s[i]);
ending[i]=update (i,root,0);
}
/// etapa 2 : faci link urile (bfs pe trie)
dq.push_back(root);
while (!dq.empty()){
nod=dq.front();
dq.pop_front();
for (i=0;i<26;i++){
if (nod->f[i]){
ant=nod->link;
while (ant && ant->f[i]==NULL){
ant=ant->link;
}
if (ant==0)
nod->f[i]->link=root;
else nod->f[i]->link=ant->f[i];
nod->f[i]->link->v.push_back(nod->f[i]); /// v e reverse-ul lui link
dq.push_back(nod->f[i]);
}
}
}
/// etapa 3 : parcurgerea sirului mare si mergand in trie in ac timp
nod=root;
for (i=0;initial[i]!=0;i++){
while (nod!=root && nod->f[initial[i]-'a']==NULL)
nod=nod->link; /// asemanator cu pasul anterior
if (nod->f[initial[i]-'a']!=NULL)
nod=nod->f[initial[i]-'a'];
nod->arrival++;
}
/// etapa 4 : sume partiale pe link uri in trie
dfs (root);
for (i=1;i<=n;i++)
fprintf (fout,"%d\n",ending[i]->arrival);
return 0;
}