Pagini recente » Cod sursa (job #1328964) | Cod sursa (job #1737282) | Cod sursa (job #1685147) | Cod sursa (job #1464560) | Cod sursa (job #759863)
Cod sursa(job #759863)
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
#define MAXA 1000001
#define MAXB 10001
struct trie{
struct trie *f[26]; // directiile catre cele 26 de litere
struct trie *fail; // muchia de intoarcere in trie
vector<int>cuv; // lista cuvintelor care se termina pe pozitia respectiva in trie
int nr; // numarul de aparitii
}*t,*c[MAXA]; //
char a[MAXA],b[MAXB];
int n,p,u,ap[101];
void adauga(int i,char *b){
trie *g=t;
int urm;
while('a'<=*b && *b<='z')
{
urm=*b-'a';
if(g->f[urm]==0)g->f[urm]=new trie;
g=g->f[urm];
b++; //urmatorul caracter
}
g->cuv.push_back(i);
}
void bfs(){
trie *g,*v;
t->fail=t;
c[p=u=1]=t;
while(p<=u)
{
g=c[p++];
for(int i=0;i<26;i++)
if(g->f[i])
{
for(v=g->fail;v!=t && v->f[i] == 0;v=v->fail);
if(g->f[i] != v->f[i])v=v->f[i];
g->f[i]->fail=v;
c[++u]=g->f[i];
}
}
t->fail=0;
}
void ahocorasick(char *b){
trie *g=t;
int urm;
while('a'<=*b && *b<='z')
{
urm=*b-'a';
while(g!=t && g->f[urm]==0)g=g->fail;
if(g->f[urm])g=g->f[urm];
g->nr++;
b++;
}
}
void antibfs(){
trie *g;
while(u>0)
{
g=c[u--];
if(g->fail)g->fail->nr += g->nr;
for(int i=0;i<g->cuv.size();i++)ap[g->cuv[i]]=g->nr;
}
}
int main(){
freopen("ahocorasick.in","r",stdin);
freopen("ahocorasick.out","w",stdout);
scanf("%s ",a);
scanf("%d ",&n);
t=new trie; // cream structura
for(int i=1;i<=n;i++)
{
scanf("%s ",b);
adauga(i,b); // adaugam cuvintul b la structura
}
bfs();
ahocorasick(a);
antibfs();
for(int i=1;i<=n;i++)printf("%d\n",ap[i]);
return 0;
}