Pagini recente » Cod sursa (job #549928) | Cod sursa (job #629328) | Cod sursa (job #2904364) | Cod sursa (job #1276725) | Cod sursa (job #796654)
Cod sursa(job #796654)
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
#define MAX_LEN_A 1000010
#define MAX_LEN_WORD 10010
#define MAX_N 110
#define CHARSET_LEN 26
struct ACNode {
ACNode()
: matchCount(0)
, fallback(NULL)
{
memset(children, 0, sizeof(children));
}
~ACNode() {
for (int i = 0; i < CHARSET_LEN; ++i) {
if (children[i]) {
delete children[i];
}
}
}
void insert(char *c, int wordIndex) {
if (*c == '\0') {
words.push_back(wordIndex);
return;
}
int childIndex = int(*c - 'a');
if (!children[childIndex]) {
children[childIndex] = new ACNode;
}
children[childIndex]->insert(c + 1, wordIndex);
}
vector< int > words;
ACNode* children[CHARSET_LEN];
int matchCount;
ACNode* fallback;
};
char A[MAX_LEN_A];
int N;
ACNode root;
int nq;
ACNode* q[MAX_N * MAX_LEN_WORD];
int res[MAX_N];
void buildACTrie() {
char w[MAX_LEN_WORD];
scanf("%d\n", &N);
for (int i = 0; i < N; ++i) {
scanf("%s", w);
root.insert(w, i);
}
nq = 0;
q[0] = &root;
root.fallback = &root;
int ind = 0;
ACNode* now;
ACNode* pi;
ACNode* next;
while (ind <= nq) {
now = q[ind];
++ind;
for (int i = 0; i < CHARSET_LEN; ++i) {
next = now->children[i];
if (!next) {
continue;
}
if (now == &root) {
next->fallback = &root;
q[++nq] = next;
continue;
}
for (pi = now->fallback; pi != &root && !pi->children[i]; pi = pi->fallback) {
;
}
if (pi->children[i]) {
pi = pi->children[i];
}
next->fallback = pi;
q[++nq] = next;
}
}
}
void processA() {
ACNode* pi = &root;
for (int i = 0; A[i] != '\0'; ++i) {
while (pi != &root && !pi->children[int(A[i] - 'a')]) {
pi = pi->fallback;
}
if (pi->children[int(A[i] - 'a')]) {
pi = pi->children[int(A[i] - 'a')];
}
++(pi->matchCount);
}
}
void computeResult() {
ACNode* now;
for (int ind = nq; ind >=0; --ind) {
now = q[ind];
for (size_t i = 0, lim = now->words.size(); i < lim; ++i) {
res[now->words[i]] += now->matchCount;
}
now->fallback->matchCount += now->matchCount;
}
}
void printResult() {
for (int i = 0; i < N; ++i) {
printf("%d\n", res[i]);
}
}
int main() {
freopen("ahocorasick.in", "r", stdin);
freopen("ahocorasick.out", "w", stdout);
scanf("%s", A);
buildACTrie();
processA();
computeResult();
printResult();
return 0;
}