题目大意:给出一些单词,和一个句子,问有多少个单词在句子中出现过。
思路:来签到吧
CODE:
#include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define P(a) ((a) - 'a') #define MAX 60 #define _MAX 1000010 using namespace std; char s[_MAX]; struct Trie{ Trie *son[26],*fail; int cnt; Trie() { memset(son,NULL,sizeof(son)); fail = NULL; cnt = 0; } void Insert(char *s) { Trie *now = this; while(*s != '\0') { if(now->son[P(*s)] == NULL) now->son[P(*s)] = new Trie(); now = now->son[P(*s)]; ++s; } ++now->cnt; } }*root; struct AC_Automaton{ void Build(int cnt) { static char s[MAX]; for(int i = 1; i <= cnt; ++i) { scanf("%s",s); root->Insert(s); } static queue<Trie *> q; while(!q.empty()) q.pop(); for(int i = 0; i < 26; ++i) if(root->son[i] != NULL) root->son[i]->fail = root,q.push(root->son[i]); while(!q.empty()) { Trie *now = q.front(); q.pop(); for(int i = 0; i < 26; ++i) if(now->son[i] != NULL) { Trie *temp = now->fail; while(temp != root && temp->son[i] == NULL) temp = temp->fail; if(temp->son[i] != NULL) temp = temp->son[i]; now->son[i]->fail = temp; q.push(now->son[i]); } } } int Ask(char *s) { int re = 0; Trie *now = root; while(*s != '\0') { while(now != root && now->son[P(*s)] == NULL) now = now->fail; if(now->son[P(*s)] != NULL) now = now->son[P(*s)]; for(Trie *temp = now; temp != root; temp = temp->fail) re += temp->cnt,temp->cnt = 0; ++s; } return re; } }solver; int cases,cnt; int main() { for(cin >> cases; cases--;) { root = new Trie(); scanf("%d",&cnt); solver.Build(cnt); scanf("%s",s); printf("%d\n",solver.Ask(s)); } return 0; }
HDU 2222 Keywords Search AC自动机
原文地址:http://blog.csdn.net/jiangyuze831/article/details/41520479