Pagini recente » Cod sursa (job #773884) | Cod sursa (job #1675085) | Cod sursa (job #2445029) | Cod sursa (job #2436366) | Cod sursa (job #1556346)
#include <algorithm>
#include <fstream>
#include <cstring>
#define SZ(x) ((int) (x).size())
using namespace std;
const int NMAX = 1000005, MMAX = 10005;
char A[NMAX];
char word[MMAX];
int answers[105];
struct Node {
int cnt;
vector<int> words;
Node *links[26], *fail;
Node():
cnt(0), words(vector<int>()), links{0}, fail(0) {}
};
void addWord(Node *node, char *s, int ind) {
if (*s == '\n' || *s == '\0') {
node->words.push_back(ind);
} else {
int p = *s - 'a';
if (node->links[p] == NULL) {
node->links[p] = new Node();
}
addWord(node->links[p], s + 1, ind);
}
}
vector<Node*> q;
void buildFail(Node *root) {
root->fail = root;
q.push_back(root);
int l = 0, r = 1;
while (l < r) {
Node* node = q[l++];
for (int i = 0; i < 26; ++i) {
if (node->links[i] != NULL) {
Node *k;
for (k = node->fail; k != root && !k->links[i]; k = k->fail);
if (k->links[i] && k->links[i] != node->links[i])
k = k->links[i];
node->links[i]->fail = k;
q.push_back(node->links[i]);
r++;
}
}
}
root->fail = NULL;
}
void countAll() {
for (int i = SZ(q) - 1; i >= 0; --i) {
Node *node = q[i];
if (node->fail) node->fail->cnt += node->cnt;
for (int p: node->words) answers[p] = node->cnt;
}
}
int main() {
ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");
fin >> A + 1;
int n = strlen(A + 1);
int m;
fin >> m;
Node *root = new Node();
for (int i = 1; i <= m; ++i) {
fin >> word;
addWord(root, word, i);
}
buildFail(root);
Node *curr = root;
for (int i = 1; i <= n; ++i) {
int p = A[i] - 'a';
while (curr->links[p] == NULL && curr != root) curr = curr->fail;
if (curr->links[p]) curr = curr->links[p];
curr->cnt++;
}
countAll();
for (int i = 1; i <= m; ++i)
fout << answers[i] << '\n';
fin.close();
fout.close();
}