Pagini recente » Cod sursa (job #1880929) | Cod sursa (job #762016) | Cod sursa (job #2690334) | Cod sursa (job #1821569) | Cod sursa (job #2543239)
#include <bits/stdc++.h>
using namespace std;
#define SIGMA 26
#define N 100100
struct trie {
vector <int> index;
trie *v[SIGMA];
trie *fail;
trie(){
fail = NULL;
for (int _it = 0; _it < SIGMA; ++_it)
v[_it] = NULL;
}
}*root, *curr, *failed;
void add (string S, int index){
trie *node = root;
int it = 0;
while (it < S.size() && node->v[S[it] - 'a'] != NULL){
node = node->v[S[it] - 'a'];
++it;
}
while (it < S.size()){
node->v[S[it] - 'a'] = new trie();
node = node->v[S[it] - 'a'];
++it;
}
node->index.push_back(index);
}
int i, n, j;
string dictionary[N];
string s;
queue <trie *> q;
int match[N];
inline void add_match (int id, int pos){
///found the id-th word from the dictionary ending at
///the pos-th letter of the checked string
match[id].push_back (pos - dictionary[id].size() + 1);
}
void find_matches (string s){
trie *node = root;
int it, jt;
for (it = 0; it < s.size(); ++it){
while (node != root && node->v[s[it] - 'a'] == NULL){
node = node->fail;
}
if (node->v[s[it] - 'a'] != NULL){
node = node->v[s[it] - 'a'];
for (jt = 0; jt < node->index.size(); ++jt){
//add_match (node->index[jt], it);
++match[node->index[jt]];
}
}
}
}
void print_matches (ostream &out){
int it, jt;
for (it = 0; it < n; ++it)
if (match[it].size()){
out << dictionary[it] << " : ";
for (jt = 0; jt < match[it].size(); ++jt)
out << match[it][jt] << " ";
out << '\n';
}
}
int main()
{
ifstream fin ("ahocorasick.in");
ofstream fout ("ahocorasick.out");
root = new trie();
fin >> s;
fin >> n;
for (i = 0; i < n; ++i){
fin >> dictionary[i];
add (dictionary[i], i);
}
for (i = 0; i < SIGMA; ++i)
if (root->v[i] != NULL){
root->v[i]->fail = root;
q.push(root->v[i]);
}
while (!q.empty()){
curr = q.front();
q.pop();
for (i = 0; i < SIGMA; ++i)
if (curr->v[i] != NULL){
failed = curr->fail;
while (failed != root && failed->v[i] == NULL){
failed = failed->fail;
}
if (failed->v[i] != NULL){
curr->v[i]->fail = failed->v[i];
for (j = 0; j < failed->v[i]->index.size(); ++j){
curr->v[i]->index.push_back(failed->v[i]->index[j]);
}
}
else{
curr->v[i]->fail = root;
}
q.push(curr->v[i]);
}
}
find_matches (s);
//print_matches (fout);
for (i = 0; i < n; ++i)
fout << match[i] << '\n';
return 0;
}