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; }
总想把每一篇文章精雕细琢之后以完美的面貌示人,就像演员在演出前都要彩排,总想准备好之后再去展现精彩的一面,但人生的每一刻都是精彩的,就算现在还不完善也要发出来,作为自己一直在学习的一种见证。