http://acm.hdu.edu.cn/showproblem.php?pid=2222
注意:
1. keyword可以相同,因此计算时要累计:cur->num++。
2. 同一个keyword在str中出现多次的话,只计算一次,所以算过后需要将num设为-1(表示已经计算了)。
对于
2
5
she
he
say
shr
her
yasherhs
5
she
he
say
sher
her
yasherhs
sher中包含:she,he,her,sher四个关键字,计算顺序:she->he->e->sher->her。
注意:匹配到一个关键字,需要继续把这个keyword中包含的其他的短的keyword都匹配了,再继续前移。
# include <cstdio>
#include <stdlib.h>
#include "memory.h"
#include "queue" const int MAX_N = 1000010; char s[MAX_N]; struct TNode {
int num;
TNode *suffix;
TNode *next[26];
TNode() {
clean();
}
void clean() {
num = 0;
suffix = NULL;
memset(next, NULL, sizeof next);
}
}; TNode *T[MAX_N]; int pos = 0; void buildTrie(char *str) {
TNode * cur = T[0];
for (int i = 0; str[i]; ++i) {
int c = str[i] - 'a';
if (cur->next[c] == NULL) {
if (T[++pos] == NULL) {
T[++pos] = new TNode();
}
cur->next[c] = T[pos];
}
cur = cur->next[c];
}
cur->num++;
} void addSuffix() {
TNode* root = T[0];
root->suffix = root;
std::queue<TNode*> qTrie;
for (int i = 0; i < 26; ++i) {
if (root->next[i] == NULL) {
root->next[i] = root;
} else {
root->next[i]->suffix = root;
qTrie.push(root->next[i]);
}
}
TNode *cur, *suf;
while (!qTrie.empty()) {
cur = qTrie.front(), qTrie.pop();
suf = cur->suffix;
for (int i = 0; i < 26; ++i) {
if (cur->next[i] == NULL) {
cur->next[i] = suf->next[i];
} else {
cur->next[i]->suffix = suf->next[i];
qTrie.push(cur->next[i]);
}
}
}
} int query(char *str) {
int ans = 0;
TNode * cur = T[0];
for (int i = 0; str[i]; ++i) {
int c = str[i] - 'a';
cur = cur->next[c];
TNode * back = cur; while (back != T[0] && back->num != -1) {
// printf("%c %d\n", str[i], back->num);
ans += back->num;
back->num = -1;
back = back->suffix;
}
}
return ans;
} void clean() {
for (int i = 0; i <= pos; ++i) {
if (T[i] != NULL) {
T[i]->clean();
}
}
pos = 0;
} int main() {
if (freopen("/Users/fripside/ClionProjects/cc150/input", "r", stdin) == NULL) {
fprintf(stderr, "error redirecting stdout\n");
}
T[0] = new TNode;
int c, t;
scanf("%d", &c);
while (c--) {
clean();
scanf("%d", &t);
while (t--) {
scanf("%s", s);
buildTrie(s);
}
addSuffix();
scanf("%s", s);
printf("%d\n", query(s));
}
return 0;
}