Pagini recente » Cod sursa (job #1738126) | Cod sursa (job #3153090) | Cod sursa (job #1620444) | Cod sursa (job #1138137) | Cod sursa (job #1606880)
#include <algorithm>
#include <vector>
#include <fstream>
#include <cstring>
#include <queue>
using namespace std;
ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");
const int SIGMA = 26;
const int MAX_N = 1000100;
const int MAX_L = 10100;
const int MAX_T = 110;
struct aho {
aho *f[SIGMA], *fail;
vector<int> cuv;
int potriv; //how many times did this prefix appear in the query word
void setFail(aho *_fail) {
fail = _fail;
}
void getFail(aho *_fail, int poz) { //the whole building process is linear because every failEdge is accessed by O(number of sons)
fail = _fail;
while(fail != fail->fail && !fail->f[poz]) { //failEdge doesn't point to ROOT and failEdge doesn't point to valid node
fail = fail->fail;
}
if(fail->f[poz] && this != fail->f[poz]) {//failEdge points either to ROOT or to a valid node (different than THIS node)
fail = fail->f[poz];
}
}
public:
aho() {
memset(f, 0, sizeof(f));
fail = NULL;
potriv = 0;
}
void insert(char *c, int ind) { //basic trie insert
if(*c == 0) {
cuv.push_back(ind);
return;
}
int v = *c - 'a';
if(!f[v]) {
f[v] = new aho();
}
f[v]->insert(c + 1, ind);
}
friend void getFailEdges();
friend void pass(char*);
friend void leavesFirst();
};
aho *R = new aho();
vector<aho*> order;
void getFailEdges() {
queue<aho*> Q;
Q.push(R);
order.push_back(R);
R->setFail(R);
while(!Q.empty()) {
aho *nod = Q.front();
Q.pop();
for(int i = 0; i < SIGMA; i++) {
if(nod->f[i]) {
nod->f[i]->getFail(nod->fail, i);
Q.push(nod->f[i]);
order.push_back(nod->f[i]);
}
}
}
R->setFail(NULL);
}
void pass(char *c) {
aho *nod = R;
while(*c) {
int v = *c - 'a';
for(nod; !nod->f[v] && nod != R; nod = nod->fail);
if(nod->f[v]) {
nod = nod->f[v];
}
nod->potriv++;
c++;
}
}
int aparitii[MAX_T];
void leavesFirst() {
for(int i = order.size() - 1; i >= 0; i--) {
aho *nod = order[i];
if(nod->fail) {
nod->fail->potriv += nod->potriv;
}
for(auto it : nod->cuv) {
aparitii[it] = nod->potriv;
}
}
}
char s[MAX_N];
char cuv[MAX_L];
int main() {
fin >> s;
int n;
fin >> n;
for(int i = 1; i <= n; i++) {
fin >> cuv;
R->insert(cuv, i);
}
getFailEdges();
pass(s);
leavesFirst();
for(int i = 1; i <= n; i++) {
fout << aparitii[i] << '\n';
}
return 0;
}