Pagini recente » Rating Bogdan Burca (burcabogdan) | Cod sursa (job #963044) | Istoria paginii eliminare-gaussiana | Cod sursa (job #1823009) | Cod sursa (job #2487447)
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");
const int SIGMA = 26;
const int NMAX = 100;
const int WORDMAX = 10000;
const int TEXTMAX = 1000000;
struct Trie
{
Trie *sons[SIGMA];
Trie *failLink, *outputLink;
vector <int> wordList;
int Count; ///dp
Trie()
{
for(int i = 0; i < SIGMA; i++)
sons[i] = NULL;
failLink = outputLink = NULL;
Count = 0;
}
};
int N;
char text[TEXTMAX + 5], word[WORDMAX + 5];
queue < Trie* > Q;
vector < Trie* > antibfs;
int freq[NMAX + 5];
Trie *root = new Trie();
void Insert(Trie *node, char *s, int wordId)
{
if(s[0] == '\0')
node-> wordList.push_back(wordId);
else
{
if(node-> sons[s[0] - 'a'] == NULL)
node-> sons[s[0] - 'a'] = new Trie();
Insert(node-> sons[s[0] - 'a'], s + 1, wordId);
}
}
void ComputeLinks()
{
root-> failLink = root-> outputLink = root;
for(int i = 0; i < SIGMA; i++)
if(root-> sons[i] != NULL)
{
root-> sons[i]-> failLink = root-> sons[i]-> outputLink = root;
Q.push(root-> sons[i]);
}
while(!Q.empty())
{
Trie *node = Q.front(); Q.pop();
for(int i = 0; i < SIGMA; i++)
if(node-> sons[i] != NULL)
{
Trie *failNode = node-> failLink;
while(failNode != root && failNode-> sons[i] != NULL)
failNode = failNode-> failLink;
if(failNode-> sons[i] != NULL && failNode-> sons[i] != node-> sons[i])
failNode = failNode-> sons[i];
node-> sons[i]-> failLink = failNode;
if((int)failNode-> wordList.size() != 0)
node-> sons[i]-> outputLink = failNode;
else
node-> sons[i]-> outputLink = failNode-> outputLink;
Q.push(node-> sons[i]);
}
}
}
void Solve(char *t)
{
Trie *node = root;
while(t[0] != '\0')
{
while(node != root && node-> sons[t[0] - 'a'] == NULL)
node = node-> failLink;
if(node-> sons[t[0] - 'a'] != NULL)
node = node-> sons[t[0] - 'a'];
node-> Count++;
t += 1;
}
Q.push(root);
while(!Q.empty())
{
Trie *n = Q.front(); Q.pop();
antibfs.push_back(n);
for(int i = 0; i < SIGMA; i++)
if(n-> sons[i] != NULL)
Q.push(n-> sons[i]);
}
reverse(antibfs.begin(), antibfs.end());
for(auto it : antibfs)
{
for(auto w : it-> wordList)
freq[w] += it-> Count;
if(it-> failLink != NULL)
it-> failLink-> Count += it-> Count;
}
for(int i = 1; i <= N; i++)
fout << freq[i] << '\n';
}
int main()
{
fin >> text;
fin >> N;
for(int i = 1; i <= N; i++)
{
fin >> word;
Insert(root, word, i);
}
ComputeLinks();
Solve(text);
return 0;
}