Pagini recente » Cod sursa (job #1498003) | Cod sursa (job #1945560) | Cod sursa (job #653424) | Cod sursa (job #2263360) | Cod sursa (job #2313191)
#include<cstring>
#include<iostream>
#include<malloc.h>
#include<queue>
#include<set>
#include<list>
using namespace std;
#define SIZEALFABET 26
typedef struct Nod{
int fii[SIZEALFABET];
list<int> output;
list<pair<int,int>> links;
Nod() {
memset(fii,0,sizeof(fii));
}
}Nod;
vector<Nod> tree;
int nbNod=1;
#define MAXTEXT 1000000
char T[MAXTEXT+1];
#define MAXCUV 10000
char cuv[MAXCUV+1];
int N; // numarul de cuvinte
void addToTree(int indexCuv){
int l=strlen(cuv);
int nod=1;
int index;
for(int i=0;i<l;i++){
index=cuv[i]-'a';
if(tree[nod].fii[index]==0){
// creare nod nou
nbNod++;
tree[nod].fii[index]=nbNod;
tree[nod].links.push_back(make_pair(index,nbNod));
Nod newnod;
tree.push_back(newnod);
nod=nbNod;
}
else{
// legatura existenta
nod=tree[nod].fii[index];
}
}
tree[nod].output.push_back(indexCuv);
}
int** g;
int *f;
void secondPhase(){
queue<int> Q;
int q;
for(int i='a';i<='z';i++){
q=g[1][i-'a'];
if(q!=1){
f[q]=1;
Q.push(q);
}
}
int r,u,v;
while(!Q.empty()){
r=Q.front(); Q.pop();
for(int i='a';i<='z';i++){
u=g[r][i-'a'];
if(u!=0){
Q.push(u);
v=f[r];
while(g[v][i-'a']==0)
v=f[v];
f[u]=g[v][i-'a'];
//tree[u].output.splice(tree[u].output.end(),tree[f[u]].output);
tree[u].output.insert(tree[u].output.end(), tree[f[u]].output.begin(), tree[f[u]].output.end());
}
}
}
}
int* C;
void searchText(){
int q = 1; // initial state (root)
int m=strlen(T);
list<int>::iterator it;
for(int i=0; i< m; i++){
while(g[q][T[i]-'a']==0)
q=f[q];
q=g[q][T[i]-'a']; // follow a goto
if(!tree[q].output.empty()){
for(it=tree[q].output.begin(); it!=tree[q].output.end(); it++){
C[*it]++;
}
}
}
}
int main() {
freopen("ahocorasick.in","r",stdin);
//freopen("aho_test20.in","r",stdin);
freopen("ahocorasick.out","w",stdout);
scanf("%s",T);
scanf("%d",&N);
C=(int*)calloc(N,sizeof(int));
Nod root;
tree.push_back(root);
tree.push_back(root);
for(int i=0;i<N;i++){
scanf("%s",cuv);
addToTree(i);
/*
string S(cuv);
if(C.find(S)==C.end()){
//addToTree();
C.insert(S);
P.push_back(S);
*/
}
g=(int**)calloc(nbNod+1,sizeof(int*));
for(int i=0;i<=nbNod; i++){
g[i]=(int*)calloc(SIZEALFABET,sizeof(int));
}
for(int i='a';i<='z'; i++){
g[1][i-'a']=1;
}
list<pair<int,int>>::iterator it;
for(it=tree[1].links.begin(); it!=tree[1].links.end(); it++){
g[1][it->first]=it->second;
}
for(int i=2;i<=nbNod;i++){
for(it=tree[i].links.begin(); it!=tree[i].links.end(); it++){
g[i][it->first]=it->second;
}
}
f=(int*)calloc(nbNod+1,sizeof(int));
secondPhase();
searchText();
for(int i=0; i<N; i++){
printf("%d\n",C[i]);
}
return 0;
}