Pagini recente » Cod sursa (job #627322) | Cod sursa (job #614889) | Cod sursa (job #1208495) | Cod sursa (job #614860) | Cod sursa (job #3304075)
#include <fstream>
#include <iostream>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
using namespace std;
static const int MAXS = 1000000 + 5; // maxim noduri în trie
static const int ALPHA = 26;
int nxt[MAXS][ALPHA];
int fail[MAXS];
vector<int> outp[MAXS];
int node_cnt = 1; // 0 = root
inline int c2i(char c) { return c - 'a'; }
int main(){
ifstream in("ahocorasick.in");
ofstream out("ahocorasick.out");
string A;
in >> A;
int lenA = (int)A.size();
int n;
in >> n;
// Construim trie-ul
for(int id = 1; id <= n; id++){
string s;
in >> s;
int u = 0;
for(size_t i = 0; i < s.size(); ++i){
int c = c2i(s[i]);
if(nxt[u][c] == 0){
nxt[u][c] = node_cnt++;
}
u = nxt[u][c];
}
outp[u].push_back(id);
}
// BFS pentru fail + completare tranziții
queue<int> q;
for(int c = 0; c < ALPHA; c++){
if(nxt[0][c] != 0){
fail[nxt[0][c]] = 0;
q.push(nxt[0][c]);
}
}
while(!q.empty()){
int u = q.front(); q.pop();
for(int c = 0; c < ALPHA; c++){
int v = nxt[u][c];
if(v != 0){
int f = fail[u];
while(f != 0 && nxt[f][c] == 0){
f = fail[f];
}
fail[v] = nxt[f][c];
// agregare output de la fail
for(size_t k = 0; k < outp[fail[v]].size(); ++k){
outp[v].push_back(outp[fail[v]][k]);
}
q.push(v);
} else {
// completăm tranziția pentru căutare rapidă
nxt[u][c] = nxt[ fail[u] ][c];
}
}
}
// Vector frecvențe
vector<long long> freq(n+1, 0LL);
// Parcurgem textul
int cur = 0;
for(int i = 0; i < lenA; i++){
int c = c2i(A[i]);
cur = nxt[cur][c];
for(size_t k = 0; k < outp[cur].size(); ++k){
freq[outp[cur][k]]++;
}
}
// Scriem rezultatele
for(int i = 1; i <= n; i++){
out << freq[i] << "\n";
}
return 0;
}