Pagini recente » Cod sursa (job #2287555) | Cod sursa (job #2544376) | Cod sursa (job #1457707) | Cod sursa (job #1665250) | Cod sursa (job #2676485)
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
ifstream f("ahocorasick.in");
ofstream g("ahocorasick.out");
struct trieNode
{
int Count;
vector < int > words;
trieNode* suffixLink;
trieNode* children[26];
trieNode()
{
Count = 0;
suffixLink = NULL;
for (int i=0; i<26; i++)
children[i] = NULL;
}
};
class trie
{
int N = 0;
int ans[101];
trieNode* root = new trieNode();
public:
void insertKey(string &key);
void computeSuffixLinks();
void query(string &text);
};
void trie :: insertKey(string &key)
{
N++;
trieNode* node = root;
for (int i=0; i<key.size(); i++)
{
int index = key[i] - 'a';
if (!node -> children[index])
node -> children[index] = new trieNode();
node = node -> children[index];
}
node -> words.push_back(N);
}
void trie :: computeSuffixLinks()
{
queue < trieNode* > q;
for (int i=0; i<26; i++)
if (root -> children[i])
{
root -> children[i] -> suffixLink = root;
q.push(root -> children[i]);
}
while (!q.empty())
{
trieNode* node = q.front();
q.pop();
for (int i=0; i<26; i++)
if (node -> children[i])
{
trieNode* aux = node -> suffixLink;
while (aux && !aux -> children[i])
aux = aux -> suffixLink;
if (aux && aux -> children[i])
node -> children[i] -> suffixLink = aux -> children[i];
else
node -> children[i] -> suffixLink = root;
q.push(node -> children[i]);
}
}
}
void trie :: query(string &text)
{
trieNode* node = root;
for (int i=0; i<text.size(); i++)
{
int index = text[i] - 'a';
if (node -> children[index])
node = node -> children[index];
else
{
trieNode* aux = node -> suffixLink;
while (aux && !aux -> children[index])
aux = aux -> suffixLink;
if (aux && aux -> children[index])
node = aux -> children[index];
else
node = root;
}
node -> Count++;
}
vector < trieNode* > antibfs;
queue < trieNode* > q;
q.push(root);
while (!q.empty())
{
trieNode* node = q.front();
q.pop();
antibfs.push_back(node);
for (int i=0; i<26; i++)
if (node -> children[i])
q.push(node -> children[i]);
}
int imax = antibfs.size() - 1;
for (int i=imax; i>=0; i--)
{
trieNode* node = antibfs[i];
for (auto word : node -> words)
ans[word] = node -> Count;
if (node -> suffixLink)
node -> suffixLink -> Count += node -> Count;
}
for (int i=1; i<=N; i++)
g << ans[i] << "\n";
}
int n;
string text, pattern;
trie T;
int main()
{
f >> text;
f >> n;
for (int i=1; i<=n; i++)
{
f >> pattern;
T.insertKey(pattern);
}
T.computeSuffixLinks();
T.query(text);
return 0;
}