Pagini recente » Cod sursa (job #2923056) | Cod sursa (job #1470346) | Cod sursa (job #40439) | Cod sursa (job #1332426) | Cod sursa (job #1233016)
#include <fstream>
#include <iostream>
#include <vector>
#include <bitset>
#include <string.h>
#include <algorithm>
#include <iomanip>
#include <math.h>
#include <time.h>
#include <stdlib.h>
#include <set>
#include <map>
#include <string>
#include <queue>
#include <deque>
using namespace std;
const char infile[] = "ahocorasick.in";
const char outfile[] = "ahocorasick.out";
ifstream fin(infile);
ofstream fout(outfile);
const int SIGMA = 30;
const int MAXA = 1000005;
const int MAXW = 10005;
const int MAXN = 105;
const int oo = 0x3f3f3f3f;
const inline int min(const int &a, const int &b) { if( a > b ) return b; return a; }
const inline int max(const int &a, const int &b) { if( a < b ) return b; return a; }
const inline void Get_min(int &a, const int b) { if( a > b ) a = b; }
const inline void Get_max(int &a, const int b) { if( a < b ) a = b; }
class FiniteAutomaton {
private:
static const int SIGMA = 26;
static const char START_LETTER = 'a';
struct Node {
Node *sons[SIGMA], *pi;
int matches;
vector <int> where;
Node () {
memset(sons, NULL, sizeof(sons));
matches = 0;
}
};
Node *Root;
vector <Node *> Q;
vector <int> Ans;
inline int getCode(char s) {
return s - START_LETTER;
}
public:
FiniteAutomaton() {
Root = new Node();
}
inline Node * getRoot() {
return Root;
}
inline void addString(Node *n, char *s, int where) {
if(!*s) {
n->where.push_back(where);
Ans.push_back(0);
return;
}
int son = getCode(*s);
if(!n->sons[son])
n->sons[son] = new Node();
addString(n->sons[son], s + 1, where);
}
inline void buildPi() {
Root->pi = Root;
Node *K = Root;
Q.push_back(Root);
for(int i = 0 ; i < Q.size() ; ++ i) {
Node *act = Q[i];
for(int son = 0 ; son < SIGMA ; ++ son)
if(act->sons[son]) {
K = act->pi;
while(K != Root && K->sons[son] == NULL)
K = K->pi;
if(K->sons[son] && K->sons[son] != act->sons[son])
K = K->sons[son];
act->sons[son]->pi = K;
Q.push_back(act->sons[son]);
}
}
}
inline void AhoCorasick(char *A) {
int n = strlen(A);
Node *K = Root;
for(int i = 0, n = strlen(A) ; i < n ; ++ i) {
int son = getCode(A[i]);
while(K != Root && !(K->sons[son]))
K = K->pi;
if(K->sons[son])
K = K->sons[son];
++ K->matches;
}
}
inline vector<int> getMatches() {
for(vector <Node*> :: reverse_iterator it = Q.rbegin(), fin = Q.rend() ; it != fin ; ++ it) {
if((*it)->pi)
(*it)->pi->matches += (*it)->matches;
for(vector <int> :: iterator i = ((*it)->where).begin(), j = ((*it)->where).end(); i != j ; ++ i)
Ans[*i] = (*it)->matches;
}
return Ans;
}
} Aho;
char A[MAXA], s[MAXW];
int N;
int main() {
fin >> A >> N;
for(int i = 0 ; i < N ; ++ i) {
fin >> s;
Aho.addString(Aho.getRoot(), s, i);
}
Aho.buildPi();
Aho.AhoCorasick(A);
vector <int> ans = Aho.getMatches();
for(auto it : ans)
fout << it << '\n';
fin.close();
fout.close();
return 0;
}