Pagini recente » Cod sursa (job #935909) | Cod sursa (job #1712333) | Cod sursa (job #1345520) | Cod sursa (job #1812456) | Cod sursa (job #1010504)
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
using namespace std;
ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");
const int MAXQ = 1000010;
const int MAXN = 10100;
struct Trie {
vector<int> sir;
int P;
Trie *Son[26], *Fail;
Trie() {
P = 0;
Fail = NULL;
memset(Son, 0, sizeof(Son));
}
};
int n, QL, QR, frec[MAXN];
Trie *coada[MAXQ];
string a, b;
int code (char a) {
return (char)a - 'a';
}
void insert(Trie *A, string::iterator it, int type) {
if (it == b.end()) {
A->sir.push_back(type);
return;
}
int cod = code(*it);
if (A->Son[cod] == 0)
A->Son[cod] = new Trie;
insert (A->Son[cod], ++it, type);
}
void read(Trie *trie) {
fin >> a; fin >> n;
for (int i = 1; i <= n; ++i) {
fin >> b;
insert (trie, b.begin(), i);
}
}
void bfs(Trie *trie) {
trie->Fail = trie;
QL = QR = 1;
coada[QL] = trie;
while (QL <= QR) {
Trie *Node = coada[QL];
++QL;
for (int i = 0; i < 26; ++i) {
if (Node -> Son[i] == 0) continue;
Trie *Cfail = Node->Fail;
while (Cfail != trie && Cfail->Son[i] == 0)
Cfail = Cfail -> Fail;
if (Cfail->Son[i] != 0 && Cfail -> Son[i] != Node -> Son[i]) // aici mai era Cfail -> Son[i] != Node -> Son[i];
Cfail = Cfail -> Son[i];
Node->Son[i]->Fail = Cfail;
coada[++QR] = Node->Son[i];
}
}
}
void ReverseBFS(Trie *trie) {
while (QR > 0) {
Trie *node = coada[QR--];
if (node->Fail != 0)
node->Fail->P += node->P;
for (unsigned i = 0; i < node->sir.size(); ++i) {
int a = node->sir[i];
frec[node->sir[i]] += node->P;
}
}
}
void aho(Trie *trie) {
bfs(trie);
Trie *Node = trie;
for (int i = 0; i < a.size(); ++i) {
char c = a[i];
while (Node->Son[code(c)] == 0 && Node != trie)
Node = Node->Fail;
if (Node->Son[code(c)] != 0)
Node = Node->Son[code(c)];
++Node->P;
}
ReverseBFS(trie);
}
void print() {
for (int i = 1; i <= n; ++i)
fout << frec[i] << "\n";
}
Trie *trie = new Trie;
int main() {
read(trie);
aho(trie);
print();
return 0;
}