Pagini recente » Cod sursa (job #704421) | Plantatie | Cod sursa (job #2129752) | Cod sursa (job #1346063) | Cod sursa (job #2313226)
#include<cstring>
#include<iostream>
#include<malloc.h>
#include<queue>
#include<vector>
#include<list>
#include<algorithm>
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
vector<string> words;
int* C; // counting frequencies
int* P; // position in words
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.insert(tree[u].output.end(), tree[f[u]].output.begin(), tree[f[u]].output.end());
}
}
}
}
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_test17.in","r",stdin);
freopen("ahocorasick.out","w",stdout);
scanf("%s",T);
scanf("%d",&N);
C=(int*)calloc(N,sizeof(int));
P=(int*)calloc(N,sizeof(int));
Nod root;
tree.push_back(root);
tree.push_back(root);
vector<string>::iterator vit;
for(int i=0;i<N;i++){
scanf("%s",cuv);
string S(cuv);
vector<string>::iterator vit;
bool found=false;
for(vit=words.begin();vit!=words.end();vit++){
if(S.compare(*vit)==0){
found=true;
break;
}
}
if(!found){
addToTree(words.size());
P[i]=words.size();
words.push_back(S);
}
else{
P[i]=vit-words.begin();
}
}
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[P[i]]);
}
return 0;
}