标签:use baidu long first roo and while std return
第一道AC自动机;
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> using namespace std; typedef long long LL; const int N=1e6+10,mod=1e9+7,inf=2e9+10; typedef struct Trie_node{ struct Trie_node *fail;//失败指针 struct Trie_node *next[27];//26子节点 int counts;//单词最后一个结点的计数 Trie_node(){ fail = NULL; counts = 0; memset(next,NULL,sizeof(next)); } }Trie; Trie *q[500010]; char keyword[55];//输入的单词 char str[1000006];//输入的模式串 int head,tail;//队列的头尾指针 //将模式串插入trie树当中 void insert(char *str,Trie_node *root) { Trie_node *p = root; int i = 0, index; while(str[i]) { index = str[i] - ‘a‘; if(p->next[index] == NULL) p->next[index] = new Trie_node(); p = p->next[index]; ++i; } p->counts++; } //建立失配fail void build_ac_automation(Trie_node *root) { int i; head = tail = 0; root->fail = NULL; q[tail++] = root; while(head!=tail) { Trie_node *temp = q[head++]; Trie_node *p = NULL; for(i = 0; i < 26; ++i) { if(temp->next[i]!=NULL) { if(temp == root) temp->next[i]->fail = root; else { p = temp->fail; while(p!=NULL) { if(p->next[i]!=NULL){ temp->next[i]->fail=p->next[i]; break; } p=p->fail; } if(p == NULL) temp->next[i]->fail = root; } q[tail++] = temp->next[i]; } } } } int query(char *s,Trie_node *root){ int len = strlen(s),cnt = 0; Trie_node *p = root; for(int i = 0; i < len; ++i) { int index = s[i] - ‘a‘; while(p->next[index]==NULL&&p!=root) p = p->fail; p = p->next[index]; p = (p==NULL)?root:p; Trie_node *temp = p; while(temp != root && temp->counts!=-1) { cnt += temp->counts; temp->counts = -1; temp = temp->fail; } } return cnt; } int T,n; char s[N]; int main() { scanf("%d",&T); while(T--) { Trie_node *root = new Trie_node(); scanf("%d",&n); for(int i = 1; i <= n; ++i) { scanf("%s",s); insert(s,root); } build_ac_automation(root); scanf("%s",str); printf("%d\n",query(str,root)); } return 0; }
HDU 2222 Keywords Search AC自动机
标签:use baidu long first roo and while std return
原文地址:http://www.cnblogs.com/zxhl/p/6516498.html