Pagini recente » Cod sursa (job #3042407) | Cod sursa (job #2331634) | Cod sursa (job #1227211) | Cod sursa (job #234318) | Cod sursa (job #2387028)
#include <bits/stdc++.h>
using namespace std;
ifstream fin ("ahocorasick.in");
ofstream fout ("ahocorasick.out");
const int L_MAX = 1000002;
const int N_MAX = 102;
struct Trie
{
Trie* sons[26];
int ap;
Trie* maxPref;
Trie* maxW;
int lg;
int apSubstr;
Trie (int nlg)
{
for(int i = 0; i < 26; i++)
sons[i] = NULL;
ap = 0;
maxPref = NULL;
maxW = NULL;
lg = nlg;
apSubstr = 0;
}
};
Trie* Root = new Trie(0);
void trieInsert (Trie* root, char* str)
{
if(str[0] == '\0')
root->ap++;
else
{
if(root->sons[str[0] - 'a'] == NULL)
root->sons[str[0] - 'a'] = new Trie(root->lg + 1);
trieInsert(root->sons[str[0] - 'a'], str + 1);
}
}
char a[L_MAX];
int n;
char w[N_MAX][L_MAX];
queue <Trie*> q;
void bfs ()
{
Root->maxPref = Root->maxW = Root;
q.push(Root);
while(!q.empty())
{
Trie* root = q.front();
q.pop();
for(int i = 0; i < 26; i++)
if(root->sons[i] != NULL)
{
root->sons[i]->maxPref = root->maxPref;
while(root->sons[i]->maxPref != Root && root->sons[i]->maxPref->sons[i] == NULL)
root->sons[i]->maxPref = root->sons[i]->maxPref->maxPref;
if(root->sons[i]->maxPref->sons[i] != NULL && root != Root)
root->sons[i]->maxPref = root->sons[i]->maxPref->sons[i];
root->sons[i]->maxW = root->sons[i]->maxPref;
if(root->sons[i]->maxW->ap == 0)
root->sons[i]->maxW = root->sons[i]->maxW->maxW;
q.push(root->sons[i]);
}
}
}
void getFreq ()
{
Trie* p = Root;
int lga = strlen(a);
for(int i = 0; i < lga; i++)
{
while(p != Root && p->sons[a[i] - 'a'] == NULL)
p = p->maxPref;
if(p->sons[a[i] - 'a'] != NULL)
p = p->sons[a[i] - 'a'];
if(p->ap > 0)
p->apSubstr++;
Trie* q = p->maxW;
while(q != Root)
{
q->apSubstr++;
q = q->maxW;
}
}
}
void printFreq (Trie* root, char *str)
{
if(str[0] == '\0')
fout << root->apSubstr << "\n";
else
printFreq(root->sons[str[0] - 'a'], str + 1);
}
int main()
{
fin >> a;
fin >> n;
for(int i = 1; i <= n; i++)
{
fin >> w[i];
trieInsert(Root, w[i]);
}
bfs();
getFreq();
for(int i = 1; i <= n; i++)
printFreq(Root, w[i]);
return 0;
}