1. 程式人生 > >HDU - 1251 統計難題 【字典樹Trie】

HDU - 1251 統計難題 【字典樹Trie】

init nan fail printf pos 小寫 out esp spa

Ignatius最近遇到一個難題,老師交給他很多單詞(只有小寫字母組成,不會有重復的單詞出現),現在老師要他統計出以某個字符串為前綴的單詞數量(單詞本身也是自己的前綴).

Input輸入數據的第一部分是一張單詞表,每行一個單詞,單詞的長度不超過10,它們代表的是老師交給Ignatius統計的單詞,一個空行代表單詞表的結束.第二部分是一連串的提問,每行一個提問,每個提問都是一個字符串.

註意:本題只有一組測試數據,處理到文件結束.
Output對於每個提問,給出以該字符串為前綴的單詞的數量.
Sample Input

banana
band
bee
absolute
acm

ba
b
band
abc

Sample Output

2
3
1
0

模板題
  1 #include<iostream>
  2 using namespace std;
  3 #include<cstdio>
  4 #include<cstring>
  5 #include<queue>
  6 const int maxn = 26;
  7 struct Node{
  8     int mark;
  9     Node *next[maxn];
 10     Node *fail;
 11     Node(){
12 mark = 0; 13 for(int i=0;i<maxn;i++) 14 next[i] = NULL; 15 } 16 ~Node(){ 17 for(int i=0;i<maxn;i++) 18 if(next[i]!=NULL) 19 delete next[i]; 20 } 21 }; 22 int v[600]; 23 struct Ac_Machine{ 24 Node *head;
25 char hash(char &s){//壓縮 26 return s-a; 27 } 28 Ac_Machine(){ 29 head = NULL; 30 } 31 void init(){ 32 if(head!=NULL) 33 delete head; 34 head = new Node(); 35 } 36 void insert(char *s,int len,int num){ 37 Node *pt = head; 38 for(int i=0;i<len;i++){ 39 int k = hash(s[i]); 40 if(pt->next[k]==NULL){ 41 pt->next[k] = new Node(); 42 pt->next[k]->fail = head; 43 } 44 pt = pt->next[k]; 45 } 46 pt->mark=num; 47 } 48 void creat_fail(){ 49 queue<Node*> *team = new queue<Node*>(); 50 head->fail = NULL; 51 for(int i=0;i<maxn;i++) 52 if(head->next[i]!=NULL) 53 team->push(head->next[i]); 54 while(!team->empty()){ 55 Node *pt = team->front(); 56 team->pop(); 57 for(int i=0;i<maxn;i++){ 58 if(pt->next[i]==NULL) 59 continue; 60 team->push(pt->next[i]); 61 Node *pd = pt->fail; 62 while(pd!=NULL&&pd->next[i]==NULL) 63 pd = pd->fail; 64 if(pd!=NULL) 65 pt->next[i]->fail = pd->next[i]; 66 } 67 } 68 delete team; 69 } 70 int get(Node *pt){ 71 int ans = 0; 72 for(int i=0;i<maxn;i++){ 73 if(pt->next[i]==NULL) 74 continue; 75 ans+=get(pt->next[i]); 76 } 77 ans +=pt->mark; 78 pt->mark = ans; 79 return ans; 80 } 81 int Matching(char *s,int len){ 82 Node *pt = head; 83 int ans = 0; 84 for(int i=0;i<len;i++){ 85 int k = hash(s[i]); 86 if(pt->next[k]==NULL) 87 return 0; 88 pt=pt->next[k]; 89 } 90 return pt->mark; 91 } 92 }; 93 Ac_Machine machine; 94 char virus[510][210]; 95 char s[20000]; 96 queue<int> ans; 97 int main(){ 98 machine.init(); 99 while(true){ 100 gets(s); 101 int len = strlen(s); 102 if(len==0) 103 break; 104 machine.insert(s,len,1); 105 } 106 machine.get(machine.head); 107 while(scanf("%s",s)!=EOF){ 108 printf("%d\n",machine.Matching(s,strlen(s))); 109 } 110 return 0; 111 }

HDU - 1251 統計難題 【字典樹Trie】