Pagini recente » Cod sursa (job #2675970) | Cod sursa (job #2453468) | Cod sursa (job #675088) | Cod sursa (job #1477552) | Cod sursa (job #2288809)
/*
#include <bits/stdc++.h>
using namespace std;
#define LA (int)(2+1e6)
#define LC (int)(2+1e4)
char a[LA],c[LC];
int n,m,p[LC],r;
void prefixe(){
int i,k=0;
for (i=0;i<=n;i++) p[i]=0;
for (i=2;i<=n;i++){
for (;k!=0&&c[k+1]!=c[i];) k=p[k];
if (c[k+1]==c[i]) k++;
p[i]=k;
}
}
void potrivire(){
int k=0,i;
r=0;
for (i=1;i<=m;i++){
for (;k!=0&&c[k+1]!=a[i];) k=p[k];
if (c[k+1]==a[i]) k++;
if (k==n) r++;
}
}
int main()
{
freopen("ahocorasick.in","r",stdin);
freopen("ahocorasick.out","w",stdout);
int nr,i;
scanf("%s%d",a+1,&nr);
m=strlen(a+1);
for (i=1;i<=nr;i++){
scanf("%s",c+1);
n=strlen(c+1);
prefixe();
potrivire();
printf("%d\n",r);
}
return 0;
}*/
#include <cstdio>
#include <cstring>
#include <cctype>
#include <vector>
#define DL 1000005
#define DN 10005
#define DA 26//dimensiunea alfabetului
using namespace std;
int lg,n,l,final[DN],ic,sc;
char tx[DL],c[DN];
struct ac {
vector<int> nd;//sirurile care se termina in nodul curent
int n0;//numarul de potriviri din nodul curent sau din fii lui
ac *f[DA],*fail;
ac() {
n0=0;
fail=NULL;
memset(f,0,sizeof(f));
}
} *q[DN*DN],*t,*p;
void ins(ac *t,char *p,int i) {//inserarea se face ca si la trie
if(!isalpha(*p)) {
t->nd.push_back(i);
return;
}
int urm=*p-'a';
if(0==t->f[urm]) t->f[urm]=new ac;
ins(t->f[urm],p+1,i);
}
void bfs(ac *t) {
ac *dolar;//unde o sa mearga fail-ul fiecarui nod
t->fail=t;
for(q[ic=sc=1]=t;ic<=sc;++ic) {
ac *fr=q[ic];
for(int i=0; i<DA; ++i) if(fr->f[i]!=NULL) {//nodul caruia ii cautam fail-ul
//ne ducem in fail pana gasim un nod care are ca fiu ultima litera a nodului sau pana ajungem in radacina
for(dolar=fr->fail;dolar!=t && dolar->f[i]==NULL;dolar=dolar->fail);
if(dolar->f[i]!=NULL && dolar->f[i]!=fr->f[i]) dolar=dolar->f[i];
fr->f[i]->fail=dolar;
q[++sc]=fr->f[i];
}
}
t->fail=NULL;
}
void antibfs(ac *t) {
//parcurgem nodurile in ordinea inversa a bfs-ului astfel fiecare nod va fi parcurs dupa ce au
//fost parcursi toti fii lui si astfel putem calcula n0
for(int i=sc; i>0; --i) {
ac *fr=q[i];
if(fr->fail!=NULL) fr->fail->n0+=fr->n0;
//parcurgem toate cuvintele care se termina in nodul curent si actualizam solutia
for(int j=0; j<fr->nd.size(); ++j) final[fr->nd[j]]=fr->n0;
}
}
int main()
{
freopen("ahocorasick.in","r",stdin);
freopen("ahocorasick.out","w",stdout);
scanf("%s",tx);
scanf("%d",&n);
t=new ac;
for(int i=1; i<=n; ++i) {
scanf("%s",c);
ins(t,c,i);
}
bfs(t);
p=t;
lg=strlen(tx);
for(int i=0; i<lg; ++i) {
int urm=tx[i]-'a';
//cautam o muchie pe care sa putem merge in jos
for(;p->f[urm]==NULL && p!=t;p=p->fail);
if(p->f[urm]!=NULL) p=p->f[urm];
++p->n0;//creste numarul de potriviri din nodul curent
}
antibfs(t);
for(int i=1; i<=n; ++i) printf("%d\n",final[i]);
return 0;
}
cout << "Hello world!" << endl;
return 0;
}