Pagini recente » Cod sursa (job #221226) | Cod sursa (job #1887150) | Cod sursa (job #2224679) | Cod sursa (job #1414742) | Cod sursa (job #1554541)
#include <bits/stdc++.h>
using namespace std;
const int kMaxLen = (int) 1e6;
const int kMaxPatternLen = (int) 1e4;
const int kMaxPatterns = 100;
const int kSigma = 26;
const int BUFF_SIZE = 4096;
struct Trie {
Trie *next[kSigma];
Trie *failLink;
int freq;
Trie() {
for (int i = 0; i < kSigma; i++) {
next[i] = NULL;
}
failLink = NULL;
freq = 0;
}
};
Trie *root;
char word[kMaxLen + 1];
char pattern[kMaxPatternLen + 1];
Trie *endLink[kMaxPatterns];
Trie *Q[kMaxPatterns * kMaxPatternLen];
int qStart, qEnd;
inline Trie *newNode() {
static Trie *buff;
static int pos = BUFF_SIZE;
if (pos == BUFF_SIZE) {
buff = new Trie[BUFF_SIZE];
pos = 0;
}
return &buff[pos++];
}
int main(void) {
ifstream in("ahocorasick.in");
ofstream out("ahocorasick.out");
in.tie(0);
ios_base::sync_with_stdio(0);
int numPatterns;
int stringLength;
Trie *curr;
root = new Trie;
in >> word >> numPatterns;
for (int i = 0; i < numPatterns; i++) {
in >> pattern;
stringLength = strlen(pattern);
curr = root;
for (int j = 0; j < stringLength; j++) {
if (curr->next[pattern[j] - 'a'] == NULL) {
curr->next[pattern[j] - 'a'] = newNode();
}
curr = curr->next[pattern[j] - 'a'];
}
endLink[i] = curr;
}
in.close();
qStart = 0;
qEnd = 0;
root->failLink = root;
for (int i = 0; i < kSigma; i++) {
if (root->next[i] != NULL) {
root->next[i]->failLink = root;
Q[qEnd++] = root->next[i];
}
}
while (qStart != qEnd) {
curr = Q[qStart++];
for (int i = 0; i < kSigma; i++) {
if (curr->next[i] != NULL) {
Trie *son = curr->next[i];
Trie *tmp = curr->failLink;
while (tmp->next[i] == NULL && tmp != root) {
tmp = tmp->failLink;
}
if (tmp->next[i] != NULL) {
son->failLink = tmp->next[i];
} else {
son->failLink = root;
}
Q[qEnd++] = son;
}
}
}
stringLength = strlen(word);
curr = root;
for (int i = 0; i < stringLength; i++) {
while (curr->next[word[i] - 'a'] == NULL && curr != root) {
curr = curr->failLink;
}
if (curr->next[word[i] - 'a']) {
curr = curr->next[word[i] - 'a'];
}
curr->freq++;
}
for (int i = qEnd - 1; i >= 0; i--) {
Q[i]->failLink->freq += Q[i]->freq;
}
for (int i = 0; i < numPatterns; i++) {
out << endLink[i]->freq << '\n';
}
out.close();
return 0;
}