Pagini recente » Cod sursa (job #2070025) | Cod sursa (job #1811095) | Cod sursa (job #2899377) | Cod sursa (job #2687166) | Cod sursa (job #2635950)
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
const int SIGMA = 26;
const int NMAX = 10005;
struct Node
{
Node* link[SIGMA] = {};
Node* suffixLink = nullptr;
int cnt = 0;
};
vector <Node*> h[NMAX];
Node* AddSon(Node* aho, char ch)
{
if (aho->link[ch - 'a'] == nullptr)
aho->link[ch - 'a'] = new Node();
return aho->link[ch - 'a'];
}
Node* AddString(Node* aho, string s)
{
for (auto& ch : s)
aho = AddSon(aho, ch);
return aho;
}
void dfs_height(Node* aho, int height)
{
h[height].push_back(aho);
for (int i = 0; i < SIGMA; ++i)
if (aho->link[i])
dfs_height(aho->link[i], height + 1);
}
void son_suffix(Node* father)
{
for (int i = 0; i < SIGMA; ++i)
{
if (father->link[i] == nullptr)
continue;
Node* son = father->link[i];
son->suffixLink = father->suffixLink;
while (son->suffixLink->link[i] == nullptr && son->suffixLink != son->suffixLink->suffixLink)
son->suffixLink = son->suffixLink->suffixLink;
if (son->suffixLink->link[i] != nullptr && son->suffixLink->link[i] != son)
son->suffixLink = son->suffixLink->link[i];
}
}
Node* Advance(Node* aho, char ch)
{
while (aho->link[ch - 'a'] == nullptr && aho != aho->suffixLink)
aho = aho->suffixLink;
if (aho->link[ch - 'a'])
aho = aho->link[ch - 'a'];
return aho;
}
int main()
{
ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");
string str;
int N;
fin >> str;
fin >> N;
Node* aho = new Node();
aho->suffixLink = aho;
vector <string> words(N);
vector <Node*> wordNode(N);
for (int i = 0; i < N; ++i)
{
fin >> words[i];
wordNode[i] = AddString(aho, words[i]);
}
dfs_height(aho, 0);
for (auto& i : h)
for (auto& j : i)
son_suffix(j);
Node* node = aho;
for (auto& x : str)
{
node = Advance(node, x);
++node->cnt;
}
reverse(begin(h), end(h));
for (auto& i : h)
for (auto& j : i)
j->suffixLink->cnt += j->cnt;
for (auto& i : wordNode)
fout << i->cnt << "\n";
fin.close();
fout.close();
return 0;
}