Pagini recente » Cod sursa (job #2821768) | Cod sursa (job #1243617) | Cod sursa (job #2471614) | Cod sursa (job #306005) | Cod sursa (job #2499396)
#include <fstream>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
ifstream cin ("ahocorasick.in");
ofstream cout ("ahocorasick.out");
struct TRIE
{
int frecv;
TRIE *next[26];
TRIE *link;
TRIE()
{
frecv = 0;
link = nullptr;
memset(next, 0, sizeof(next));
}
};
TRIE *root = new TRIE();
vector <TRIE*> leafs;
void insert_letter(TRIE *&node, const string &s, int poz)
{
if(poz == s.size()) {
leafs.push_back(node);
return;
}
int next_node = s[poz] - 'a';
if(node -> next[next_node] == nullptr) {
node -> next[next_node] = new TRIE();
}
insert_letter(node -> next[next_node], s, poz + 1);
}
int main()
{
string d;
int n;
cin>>d>>n;
for(int i = 1; i <= n; ++i) {
string s;
cin>>s;
insert_letter(root, s, 0);
}
queue <TRIE*> q;
stack <TRIE*> st;
q.push(root);
while(!q.empty()) {
auto a = q.front();
st.push(a);
q.pop();
for(int i = 0; i < 26; ++i) {
if(a -> next[i] != nullptr) {
auto aux = a -> link;
while(aux != nullptr && aux != root && aux -> link != nullptr && aux -> link -> next[i] != nullptr) {
aux = aux -> link;
}
if(aux == nullptr)
aux = root;
if(aux == root) {
if(a != root && root -> next[i] != nullptr)
a -> next[i] -> link = root -> next[i];
else
a -> next[i] -> link = root;
}
else
a -> next[i] -> link = aux -> next[i];
q.push(a -> next[i]);
}
}
}
auto curr = root;
for(int i = 0; i < d.size(); ++i) {
if(curr == nullptr)
curr = root;
while(curr != root && curr != nullptr && curr -> next[d[i] - 'a'] == nullptr)
curr = curr -> link;
if(curr != nullptr)
curr = curr -> next[d[i] - 'a'];
if(curr != nullptr)
curr -> frecv += 1;
}
while(st.size()) {
auto vf = st.top();
st.pop();
if(vf -> link != nullptr)
vf -> link -> frecv += vf -> frecv;
}
for(auto x: leafs)
cout<<x -> frecv<<"\n";
return 0;
}