Pagini recente » Cod sursa (job #272797) | Cod sursa (job #2428540) | Cod sursa (job #221492) | Cod sursa (job #1457596) | Cod sursa (job #3308083)
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
#define CMAX 10001
#define NMAX 101
struct trie{
trie*fiu[26],*backedge;
int cnt=0;
trie(){
cnt=0;
for(int i=0;i<26;++i){
fiu[i]=nullptr;
}
backedge=nullptr;
}
};
char str[CMAX];
vector<trie*>nods;
trie*root=new trie(),*cuvinte[NMAX];
trie*insert(trie*nod,char*s){ // insert ca si intr-o trie normala
if(*s=='\0'){
return nod;
}
if(nod->fiu[*s-'a']==nullptr){
nod->fiu[*s-'a']=new trie();
}
return insert(nod->fiu[*s-'a'],s+1);
}
void bfs(){ // formarea de noduri pe backedgeuri
queue<trie*>Q;
Q.push(root);
while(!Q.empty()){
trie*nod=Q.front();
nods.push_back(nod);
Q.pop();
for(int i=0;i<26;++i){
if(nod->fiu[i]!=nullptr){
trie*backedge=nod->backedge;
while(backedge!=nullptr&&backedge->fiu[i]==nullptr){ // parcurgearea pe backedge cat de mult se poate
backedge=backedge->backedge;
}
if(backedge==nullptr){
backedge=root;
}else{
backedge=backedge->fiu[i];
}
nod->fiu[i]->backedge=backedge; // setarea backedgeului fiului in backedgeu corespunzator
Q.push(nod->fiu[i]);
}
}
}
}
void match(string word){ // matchingu de main word pe trie
trie*nod=root;
for(auto c:word){
while(nod!=nullptr&&nod->fiu[c-'a']==nullptr){
nod=nod->backedge;
}
if(nod==nullptr){
nod=root;
}else{
nod=nod->fiu[c-'a'];
}
++nod->cnt;
}
}
void update(){ // actualizarea de 'pseudo-propagare' a cnt-ului in muchile de unde a provenit
while(!nods.empty()){
trie*nod=nods.back();
nods.pop_back();
if(nod->backedge!=nullptr){
nod->backedge->cnt+=nod->cnt;
}
}
}
int main(){
#ifdef LOCAL
#else
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
#endif
freopen("ahocorasick.in","r",stdin);
freopen("ahocorasick.out","w",stdout);
string word;
cin>>word;
int n;
cin>>n;
for (int i=0;i<n;++i){
cin>>str;
cuvinte[i]=insert(root,str); // memorarea pointerilor de end a cuvintelor
}
bfs();
match(word);
update();
for(int i=0;i<n;++i){
cout<<cuvinte[i]->cnt<<"\n";
}
return 0;
}