Pagini recente » Cod sursa (job #1164200) | Cod sursa (job #2524599) | Cod sursa (job #1129147) | Cod sursa (job #947097) | Cod sursa (job #1204883)
#include <algorithm>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
class AhoCorasick {
public:
AhoCorasick():
Nodes(vector<AhoCorasickNode>(1)),
BfsOrder(vector<int>()),
CountWords(0) {}
void insert(const string &S)
{
int node = 0;
for (int i = 0; i < int(S.size()); i++)
{
if (!Nodes[node].links[S[i] - 'a'])
{
Nodes[node].links[S[i] - 'a'] = Nodes.size();
Nodes.push_back(AhoCorasickNode());
}
node = Nodes[node].links[S[i] - 'a'];
}
Nodes[node].words.push_back(CountWords++);
}
void build()
{
BfsOrder.push_back(0);
for (int i = 0; i < int(BfsOrder.size()); i++)
{
const int node = BfsOrder[i];
for (int j = 0; j < 26; j++)
{
if (!Nodes[node].links[j]) continue;
int k;
for (k = Nodes[node].fail; !Nodes[k].links[j] && k; k = Nodes[k].fail);
if (Nodes[k].links[j] && Nodes[k].links[j] != Nodes[node].links[j]) k = Nodes[k].links[j];
Nodes[Nodes[node].links[j]].fail = k;
BfsOrder.push_back(Nodes[node].links[j]);
}
}
}
vector<int> getFreqs(const string &S)
{
vector<int> Frequences = vector<int>(CountWords, 0);
for (int i = 0, node = 0; i < int(S.size()); i++)
{
for (; !Nodes[node].links[S[i] - 'a'] && node; node = Nodes[node].fail);
if (Nodes[node].links[S[i] - 'a']) node = Nodes[node].links[S[i] - 'a'];
Nodes[node].count++;
}
for (int i = BfsOrder.size() - 1; i >= 0; i--)
{
const int node = BfsOrder[i];
Nodes[Nodes[node].fail].count += Nodes[node].count;
for (const int p: Nodes[node].words) Frequences[p] = Nodes[node].count;
}
return Frequences;
}
private:
class AhoCorasickNode {
public:
int count, fail;
int links[26];
vector<int> words;
AhoCorasickNode():
count(0),
fail(0),
links{0},
words(vector<int>()){}
};
vector<AhoCorasickNode> Nodes;
vector<int> BfsOrder;
int CountWords;
};
string S;
int main()
{
ifstream cin("ahocorasick.in");
ofstream cout("ahocorasick.out");
cin >> S;
int T;
cin >> T;
AhoCorasick A;
while (T--)
{
string Word;
cin >> Word;
A.insert(Word);
}
A.build();
vector<int> Freq = A.getFreqs(S);
for(const int p: Freq) cout << p << "\n";
cin.close();
cout.close();
}