Pagini recente » Cod sursa (job #2867131) | Cod sursa (job #312791) | Cod sursa (job #898451) | Clasament td | Cod sursa (job #2877689)
#include <bits/stdc++.h>
using namespace std;
ifstream f("ahocorasick.in");
ofstream g("ahocorasick.out");
struct aho
{
int letter, cnt;
aho *next[26], *par, *fail, *exit;
vector<int> leafs;
// string ss;
aho()
{
letter = cnt = 0;
for (int i = 0; i < 26; i++)
next[i] = nullptr;
par = fail = exit = nullptr;
leafs.clear();
}
} *root = new aho;
struct box
{
aho *x;
box(aho *i) { x = i; }
};
string text;
int n, af[102];
vector<string> v;
void adauga(const string &, int);
void prepare_aho();
void process_text();
void get_results();
// void print_aho();
int32_t main()
{
f >> text >> n;
root->par = root;
for (int i = 1; i <= n; i++)
{
static string s;
f >> s;
adauga(s, i);
}
prepare_aho();
process_text();
get_results();
for (int i = 1; i <= n; i++)
g << af[i] << '\n';
return 0;
}
// void print_aho()
// {
// queue<box> q;
// q.push(box(root));
// while (!q.empty())
// {
// aho *ax = q.front().x;
// q.pop();
// g << ax->ss << " " << ax->fail->ss << '\n';
// for (int i = 0; i < 26; i++)
// if (ax->next[i] != nullptr)
// q.push(ax->next[i]);
// }
// }
void adauga(const string &s, int x)
{
aho *ax = root;
for (const char &ch : s)
{
if (ax->next[ch - 'a'] == nullptr)
{
ax->next[ch - 'a'] = new aho;
ax->next[ch - 'a']->letter = ch - 'a';
}
ax->next[ch - 'a']->par = ax;
ax = ax->next[ch - 'a'];
// ax->ss = ax->par->ss + ch;
}
ax->leafs.push_back(x);
}
void prepare_aho()
{
queue<box> q;
q.push(box(root));
while (!q.empty())
{
aho *ax = q.front().x;
q.pop();
if (ax == root)
ax->fail = ax->exit = root;
else if (ax->par == root)
{
ax->fail = root;
if (!ax->leafs.empty())
ax->exit = ax;
else
ax->exit = root;
}
else
{
aho *j = ax->par->fail;
while (true)
{
if (j->next[ax->letter] != nullptr)
{
ax->fail = j->next[ax->letter];
break;
}
if (j == root)
{
ax->fail = root;
break;
}
j = j->fail;
}
if (!ax->leafs.empty())
ax->exit = ax;
else
ax->exit = ax->fail->exit;
}
for (int i = 0; i < 26; i++)
if (ax->next[i] != nullptr)
q.push(box(ax->next[i]));
}
}
void process_text()
{
aho *ax = root;
for (const char &ch : text)
{
while (true)
{
if (ax->next[ch - 'a'] != nullptr)
{
ax = ax->next[ch - 'a'];
break;
}
if (ax == root)
break;
ax = ax->fail;
}
ax->cnt++;
// aho *cr = ax;
// while (true)
// {
// cr = cr->exit;
// if (cr == root)
// break;
// for (const int &i : cr->leafs)
// af[i]++;
// cr = cr->fail;
// }
}
}
void get_results()
{
queue<box> q;
stack<box> st;
q.push(box(root));
while (!q.empty())
{
aho *ax = q.front().x;
st.push(q.front());
q.pop();
for (int i = 0; i < 26; i++)
if (ax->next[i] != nullptr)
q.push(box(ax->next[i]));
}
while (!st.empty())
{
aho *ax = st.top().x;
st.pop();
for (const int &i : ax->leafs)
af[i] += ax->cnt;
ax->fail->cnt += ax->cnt;
}
}