Pagini recente » Cod sursa (job #2637160) | Cod sursa (job #2128415) | Cod sursa (job #1853788) | Cod sursa (job #1396657) | Cod sursa (job #2763834)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");
struct node {
node* to[26]; node* lps; int nr;
node() {memset(to, NULL, sizeof(to)); lps = NULL; nr = 0;}
node* go_to(char ch) { if(!to[ch - 'a']) return to[ch - 'a'] = new node(); return to[ch - 'a']; }
};
class trie {
private:
vector <node*> t, nodes;
int k, n;
public:
node* root = new node();
void build(vector <string>& v) {
root -> lps = root; n = (int)v.size();
for(auto s : v) {
node* curr = root;
for(auto ch : s) curr = curr -> go_to(ch);
t.push_back(curr);
}
node* aux; nodes.push_back(root); k = 0;
while(k < (int)nodes.size()) {
//cerr << k << " ";
node* top = nodes[k++];
for(short ch = 0; ch < 26; ch++) if(top -> to[ch]) {
for(aux = top -> lps; aux != root && !aux -> to[ch]; aux = aux -> lps);
//cerr << "Entered if for ch " << ch << "\n";
if(aux -> to[ch] && aux != top) top -> to[ch] -> lps = aux -> to[ch];
else top -> to[ch] -> lps = root;
nodes.push_back(top -> to[ch]);
}
}
}
vector <int> solve(string s) {
int len = s.length(); node* sn = root;
for(int i = 0; i < len; i++) {
short ch = s[i] - 'a';
for(; sn != root && !sn -> to[ch]; sn = sn -> lps);
if(sn -> to[ch]) sn = sn -> to[ch];
sn -> nr++;
}
for(int i = k - 1; i >= 0; i--) nodes[i] -> lps -> nr += nodes[i] -> nr;
vector <int> res(n);
for(int i = 0; i < n; i++) res[i] = t[i] -> nr;
return res;
}
};
string s;
vector <string> dict;
int n;
int main()
{
fin >> s;
fin >> n; dict.resize(n);
for(int i = 0; i < n; i++) fin >> dict[i];
trie T; T.build(dict);
vector <int> sol = T.solve(s);
for(int i = 0; i < n; i++) fout << sol[i] << "\n";
return 0;
}