Pagini recente » Cod sursa (job #1544298) | Cod sursa (job #1911764) | Cod sursa (job #22896) | Cod sursa (job #1075648) | Cod sursa (job #663589)
Cod sursa(job #663589)
#include<fstream>
#include<vector>
#define NMAX 10024
#define CH(a) a-'a'
using namespace std;
vector <int> sol[NMAX*NMAX];
struct Trie{int inf;
Trie *fiu[26],*fail;};
inline void seT_Trie(Trie *nod) {
int i;
nod->inf=0;
nod->fail=0;
for(i=0;i<26;i++)
nod->fiu[i]=0;
}
struct w{Trie *nod;}deque[NMAX*NMAX];
Trie *T=new Trie;
char A[NMAX*100];
int n,ord,SOL[NMAX];
void afis() {
int i;
ofstream out("ahocorasick.out");
for(i=1;i<=n;i++)
out<<SOL[i]<<'\n';
out.close();
}
void addtoSol(int k) {
int i;
for(i=0;i<sol[k].size();i++)
SOL[sol[k][i]]++;
}
void solve() {
int i;
Trie *nod=T;
for(i=0;i<A[i];i++) {
while(!nod->fiu[CH(A[i])]&&nod!=T)
nod=nod->fail;
if(nod->fiu[CH(A[i])])
nod=nod->fiu[CH(A[i])];
if(nod->inf)
addtoSol(nod->inf);
}
}
void calc_fail() {
int i,nr=0,j;
Trie *nod,*p;
T->fail=T;
for(i=0;i<26;i++)
if(T->fiu[i]) {
deque[nr++].nod=T->fiu[i];
T->fiu[i]->fail=T;
}
for(i=0;i<nr;i++) {
nod=deque[i].nod;
for(j=0;j<26;j++) {
p=nod;
if(nod->fiu[j]) {
while(p!=T) {
if(p->fail->fiu[j]) {
nod->fiu[j]->fail=p->fail->fiu[j];
break;
}
else
p=p->fail;
}
p=nod->fiu[j];
if(!p->fail)
p->fail=T;
deque[nr++].nod=nod->fiu[j];
if(p->fail->inf) {
if(!p->inf) {
p->inf=++ord;
sol[ord].insert(sol[ord].end(),sol[p->fail->inf].begin(),sol[p->fail->inf].end());
}
else
sol[p->inf].insert(sol[p->inf].begin(),sol[p->fail->inf].begin(),sol[p->fail->inf].end());
}
}
}
}
}
void citire() {
int i,j;
char cuv[1024];
Trie *nod;
ifstream in("ahocorasick.in");
in.getline(A,NMAX*100-2);
seT_Trie(T);
in>>n;
in.getline(cuv,2);
for(i=0;i<n;i++) {
in.getline(cuv,1010);
nod=T;
for(j=0;j<cuv[j];j++) {
if(nod->fiu[CH(cuv[j])]==0) {
nod->fiu[CH(cuv[j])]=new Trie;
seT_Trie(nod->fiu[CH(cuv[j])]);
}
nod=nod->fiu[CH(cuv[j])];
}
++ord;
if(!nod->inf) {
nod->inf=ord;
sol[ord].push_back(ord);
}
else
sol[nod->inf].push_back(ord);
}
in.close();
}
int main() {
citire();
calc_fail();
solve();
afis();
return 0;
}