Pagini recente » Cod sursa (job #1698262) | Cod sursa (job #1245546) | Cod sursa (job #2153492) | Cod sursa (job #677435) | Cod sursa (job #2674417)
#include <fstream>
#include <queue>
using namespace std;
ifstream f("ahocorasick.in");
ofstream g("ahocorasick.out");
struct trieNode
{
bool isEndOfWord;
int word;
char c;
trieNode* suffix;
trieNode* dictionarySuffix;
trieNode* parent;
trieNode* children[26];
trieNode(trieNode* Parent, char ch)
{
isEndOfWord = false;
c = ch;
suffix = NULL;
dictionarySuffix = NULL;
parent = Parent;
for (int i=0; i<26; i++)
children[i] = NULL;
}
};
class trie
{
private:
int N;
int ans[101];
trieNode* root = new trieNode(NULL, 0);
queue < trieNode* > q;
void insertKey(string key, int ind);
public:
void insertKeys(string keys[101], int n);
void getSuffixes();
void getDictionarySuffixes();
void query(string &text);
};
void trie :: insertKey(string key, int ind)
{
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, key[i]);
node = node -> children[index];
}
node -> isEndOfWord = true;
node -> word = ind;
}
void trie :: insertKeys(string keys[101], int n)
{
N = n;
for (int i=1; i<=n; i++)
insertKey(keys[i], i);
}
void trie :: getSuffixes()
{
q.push(root);
while(!q.empty())
{
trieNode* node = q.front();
q.pop();
for (int i=0; i<26; i++)
if (node -> children[i])
q.push(node -> children[i]);
if (node == root)
continue;
if (node -> parent == root)
{
node -> suffix = root;
continue;
}
trieNode* p = node -> parent -> suffix;
int index = node -> c - 'a';
while (p != root && !p -> children[index])
p = p -> suffix;
if (p -> children[index] && p != node -> parent)
node -> suffix = p -> children[index];
else
node -> suffix = NULL;
}
}
void trie :: getDictionarySuffixes()
{
q.push(root);
while (!q.empty())
{
trieNode* node = q.front();
q.pop();
for (int i=0; i<26; i++)
if (node -> children[i])
q.push(node -> children[i]);
if (node == root)
continue;
if (node -> parent == root)
continue;
trieNode* p = node -> suffix;
while (p && !p -> isEndOfWord)
p = p -> suffix;
if (p && p -> isEndOfWord)
node -> dictionarySuffix = p;
}
}
void trie :: query(string &text)
{
int n = text.size();
trieNode* node = root;
for (int i=0; i<n; i++)
{
int index = text[i] - 'a';
if (node -> children[index])
node = node -> children[index];
else
{
trieNode* p = node -> suffix;
while (p && !p -> children[index])
p = p -> suffix;
if (p && p -> children[index])
node = p -> children[index];
else
node = root;
}
ans[node -> word] += node -> isEndOfWord;
trieNode *aux = node;
while (aux -> dictionarySuffix)
{
aux = aux -> dictionarySuffix;
ans[aux -> word]++;
}
}
for (int i=1; i<=N; i++)
g << ans[i] << "\n";
}
int n;
string text;
string pattern[101];
trie t;
int main()
{
f >> text;
f >> n;
for (int i=1; i<=n; i++)
f >> pattern[i];
t.insertKeys(pattern, n);
t.getSuffixes();
t.getDictionarySuffixes();
t.query(text);
return 0;
}