Pagini recente » Cod sursa (job #3193438) | Cod sursa (job #2343440) | Cod sursa (job #1071476) | Cod sursa (job #809717) | Cod sursa (job #724430)
Cod sursa(job #724430)
#include<stdio.h>
#include<string.h>
#include<vector>
#include<queue>
#include<string>
using namespace std;
#define maxn (1<<20)
char sir[maxn];
struct trie_node{
bool final;
int nr_sol;
int children[26];
vector <int> solutii;
int fail;
int tata;
trie_node() {
final = false;
nr_sol = 0;
fail = 0;
memset(children, 0, sizeof(children));
};
};
struct trie{
vector <trie_node> nodes;
int rad;
trie() {
trie_node a;
nodes.push_back(a);
nodes.push_back(a);
rad = 1;
}
void add(char *, int);
void complete_root();
void fail_function();
void run_for_word( char *, int *);
};
void trie::add( char *cuvant, int indice) {
int nod_act = rad;
string cuv(cuvant);
int len = cuv.size();
int i = 0;
while( nodes[nod_act].children[cuv[i]-'a'] != 0 && i < len) {
nod_act = nodes[nod_act].children[cuv[i]-'a'];
i++;
}
for( ; i < len; ++i) {
trie_node a;
a.tata = nod_act;
nodes.push_back(a);
nodes[nod_act].children[cuv[i]-'a'] = nodes.size() - 1;
nod_act = nodes.size() - 1;
}
nodes[nod_act].final = true;
nodes[nod_act].nr_sol++;
nodes[nod_act].solutii.push_back(indice);
}
void trie::complete_root() {
for( int i = 0; i < 26; ++i) {
if( nodes[rad].children[i] == 0)
nodes[rad].children[i] = rad;
}
}
void trie::fail_function() {
queue<int> coada;
for( int i = 0; i < 26; ++i) {
int q = nodes[rad].children[i] ;
if( q != rad)
nodes[q].fail = 1, coada.push(q);
}
while( coada.size() ) {
int nod = coada.front();
coada.pop();
for( int i = 0; i < 26; ++i) {
if( nodes[nod].children[i] == 0) continue;
int next_nod = nodes[nod].children[i];
coada.push(next_nod);
int v = nodes[nod].fail;
while( nodes[v].children[i] == 0 )
v = nodes[v].fail;
nodes[next_nod].fail = nodes[v].children[i];
trie_node temp = nodes[nodes[v].children[i]];
nodes[next_nod].nr_sol += temp.nr_sol;
for( int i = 0; i< temp.solutii.size(); ++i)
nodes[next_nod].solutii.push_back(temp.solutii[i]);
}
}
}
void trie::run_for_word( char *sir, int *rez) {
int m = strlen(sir);
int nod_act = rad;
for( int i = 0; i < m; ++i ) {
while( nodes[nod_act].children[sir[i] -'a'] == 0 )
nod_act = nodes[nod_act].fail;
nod_act = nodes[nod_act].children[sir[i]-'a'];
for( int j = 0; j < nodes[nod_act].solutii.size(); ++j)
rez[ nodes[nod_act].solutii[j]]++;
}
}
int main() {
freopen("ahocorasick.in", "r", stdin);
freopen("ahocorasick.out", "w", stdout);
int nr_cuv;
scanf("%s\n%d", sir, &nr_cuv);
trie tri;
for( int i = 0; i < nr_cuv; ++i) {
char temp_cuv[10001];
scanf("%s", temp_cuv);
tri.add (temp_cuv, i);
}
tri.complete_root();
tri.fail_function();
int *rezultate = new int[nr_cuv];
for( int i = 0; i < nr_cuv; ++i)
rezultate[i] = 0;
tri.run_for_word(sir, rezultate);
for( int i = 0; i < nr_cuv; ++i) {
printf("%d\n", rezultate[i]);
}
return 0;
}