重新整理Trie的内容,还有一种叫做双链键树,不过到现在也不会写。
Trie 可以称为字典树,也叫做前缀树,叫字典树很形象,叫前缀树可以很好的区分,因为还有一种树叫做后缀树
自己就不瞎总结了,写估计也写不好。关键是时间不允许。
先给一个比较标准的模板
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 5 using namespace std; 6 7 #define MAXBRANCH 26 8 #define CLR(a,b) memset(a,b,sizeof(a)) 9 10 typedef struct _TRIENODE_ 11 { 12 bool isStr; 13 _TRIENODE_* pNext[MAXBRANCH]; 14 15 }TrieNode,*PTrieNode; 16 17 PTrieNode CreateNode() 18 { 19 PTrieNode Node = (PTrieNode)malloc(sizeof(TrieNode)); 20 for(int i=0;i<MAXBRANCH;i++) 21 Node->pNext[i] = NULL; 22 Node->isStr = false; 23 return Node; 24 } 25 26 void Insert(PTrieNode Root,char* words) 27 { 28 PTrieNode Location = Root; 29 while(*words) 30 { 31 if(Location->pNext[*words - 'a'] == NULL) 32 { 33 Location->pNext[*words - 'a'] = CreateNode(); 34 } 35 36 Location = Location->pNext[*words - 'a']; 37 38 words++; 39 } 40 41 Location->isStr = true; 42 } 43 44 45 bool Search(PTrieNode Root,char* words) 46 { 47 PTrieNode Location = Root; 48 while(*words != '\0' && Location->pNext[*words - 'a'] != NULL) 49 { 50 Location = Location->pNext[*words - 'a']; 51 words++; 52 } 53 54 return (Location!=NULL && Location->isStr == true); 55 } 56 57 void Delete(PTrieNode Root) 58 { 59 for(int i=0;i<MAXBRANCH;i++) 60 { 61 if(Root->pNext[i] != NULL) 62 { 63 Delete(Root->pNext[i]); 64 } 65 } 66 67 free(Root); 68 } 69 70 71 int main() 72 { 73 74 char test[4][100] = {"iloveyou","mylove","dont","oh"}; 75 char* str = (char*)malloc(sizeof(char)*100); 76 PTrieNode Root = CreateNode(); 77 78 for(int i=0;i<4;i++) 79 { 80 printf("%s\n",test[i]); 81 Insert(Root,test[i]); 82 } 83 84 printf("Input string to search:"); 85 gets(str); 86 if(Search(Root,str)) 87 printf("Finded!"); 88 else 89 printf("Failed!"); 90 91 return 0; 92 }
然后给一个比较简洁的可以比赛用的模板
#include <cstdio> #include <cstring> #include <algorithm> #define CLR(a,b) memset(a,b,sizeof(a)) using namespace std; struct trie { struct node { int cnt; node* next[26]; }; node* rt; void init() { rt = CreateNode(); } node* CreateNode() { node* t = new node; for(int i=0;i<26;i++) t->next[i] = NULL; t->cnt = 0; return t; } void insert(char* str) { node* p = rt; while(*str) { int t = *str - 'a'; if(p->next[t] == NULL) p->next[t] = CreateNode(); p = p->next[t]; str++; } p->cnt++; } bool search(char* str) { node* p = rt; while(*str && p) { p = p->next[*str - 'a']; str++; } return (p && p->cnt); } void del(node* root) { if(root == NULL) return; else { for(int i=0;i<26;i++) { if(root->next[i]) del(root->next[i]); } } delete root; } }Trie; int main() { char test[4][100] = {"iloveyou","mylove","dont","oh"}; char* str = (char*)malloc(sizeof(char)*100); Trie.init(); for(int i=0;i<4;i++) { printf("%s\n",test[i]); Trie.insert(test[i]); } printf("Input string to search: "); gets(str); if(Trie.search(str)) printf("YES!"); else printf("NO!"); return 0; }
然后是三道水题,先来这三道,其他的以后补充
HDU 1075 what are you tlaking about?
/* 简要说明题意:题目意思很清楚,就是外星人给了你一本日记和一本字典,你需要把日记通过字典来翻译。 分析:需要增加一个域来存放单词的明文,翻译的时候找到单词的密文,需要对应输出单词的明文,还要注意其他ascii字符的输出,然后就是裸的Trie了 */
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<algorithm> 5 6 using namespace std; 7 #define CLR(a,b) memset(a,b,sizeof(a)) 8 #define MAXBRANCH 26 9 10 char str[20]; 11 char s1[20],s2[20],s3[3003]; 12 13 typedef struct _TRIENODE_ 14 { 15 bool isStr; 16 _TRIENODE_* pNext[MAXBRANCH]; 17 char Dir[15]; 18 }TrieNode,*PTrieNode; 19 20 PTrieNode CreateNode() 21 { 22 PTrieNode Node = (PTrieNode)malloc(sizeof(TrieNode)); 23 for(int i=0;i<MAXBRANCH;i++) 24 { 25 Node->pNext[i] = NULL; 26 } 27 28 Node->isStr = false; 29 CLR(Node->Dir,0); 30 return Node; 31 } 32 33 void Insert(PTrieNode Root,char* words) 34 { 35 PTrieNode Location = Root; 36 while(*words) 37 { 38 if(Location->pNext[*words - 'a'] == NULL) 39 { 40 Location->pNext[*words - 'a'] = CreateNode(); 41 } 42 Location = Location->pNext[*words - 'a']; 43 words++; 44 } 45 Location->isStr = true; 46 strcpy(Location->Dir,s1); 47 } 48 49 bool Search(PTrieNode Root,char* words) 50 { 51 PTrieNode Location = Root; 52 while(*words) 53 { 54 if(Location->pNext[*words - 'a'] == NULL) 55 return false; 56 Location = Location->pNext[*words - 'a']; 57 words++; 58 } 59 if(Location->isStr) 60 { 61 printf("%s",Location->Dir); 62 return true; 63 } 64 } 65 void Delete(PTrieNode Root) 66 { 67 for(int i=0;i<MAXBRANCH;i++) 68 { 69 if(Root->pNext[i] != NULL) 70 { 71 Delete(Root->pNext[i]); 72 } 73 } 74 75 free(Root); 76 } 77 78 int main() 79 { 80 scanf("%s",str); 81 PTrieNode Root = CreateNode(); 82 while(scanf("%s %s",s1,s2) && strcmp("END",s1)!=0) 83 { 84 Insert(Root,s2); 85 CLR(s1,0);CLR(s2,0); 86 } 87 getchar(); 88 while(gets(s3) && strcmp(s3,"END")!=0) 89 { 90 char* se = s3; 91 char* st = s3; 92 while(*st) 93 { 94 CLR(str,0); 95 int len = 0; 96 while(*st>='a' && *st <= 'z') st++,len++; 97 if(len) 98 { 99 strncpy(str,se,len); 100 if(!Search(Root,str)) 101 printf("%s",str); 102 } 103 else 104 { 105 printf("%c",*st); 106 st++; 107 } 108 se = st; 109 } 110 CLR(s3,0); 111 printf("\n"); 112 } 113 return 0; 114 }
HDU 1247 Hat's words
/* 题意:先读入所有单词,并插入字典,然后问,哪些单词是hat's words(由两个已经在字典里的单词组成) 分析:对每一个单词进行拆分,拆分成两部分,并在字典中查找,如果均查找到,则为所求 */
1 #include<cstdio> 2 #include<cstring> 3 #include<malloc.h> 4 using namespace std; 5 #define CLR(a,b) memset(a,b,sizeof(a)) 6 7 struct Trie 8 { 9 struct Node 10 { 11 Node* next[26]; 12 int cnt; 13 }; 14 15 Node* root; 16 17 void Init() 18 { 19 root = CreateNode(); 20 } 21 22 Node* CreateNode() 23 { 24 Node* tmp = (Node*)malloc(sizeof(Node)); 25 for(int i=0;i<26;i++) 26 tmp->next[i] = NULL; 27 tmp->cnt = 0; 28 return tmp; 29 } 30 31 void Insert(char* str) 32 { 33 Node* p = root; 34 while(*str) 35 { 36 int t = *str - 'a'; 37 if(p->next[t] == NULL) 38 p->next[t] = CreateNode(); 39 p = p->next[t]; 40 str++; 41 } 42 p->cnt++; 43 } 44 45 int Search(char* str) 46 { 47 Node* p = root; 48 while(*str && p) 49 { 50 p = p->next[*str - 'a']; 51 str++; 52 } 53 return (p && p->cnt); 54 } 55 56 void Delete(Node* rt) 57 { 58 if(rt == NULL) 59 return; 60 for(int i=0;i<26;i++) 61 { 62 if(rt->next[i]) 63 { 64 Delete(rt->next[i]); 65 } 66 } 67 free(rt); 68 } 69 }Trie; 70 71 char words[50005][110]; 72 73 int main() 74 { 75 int i = 0, j = 0, n = 0; 76 Trie.Init(); 77 while(gets(words[n])) 78 { 79 Trie.Insert(words[n++]); 80 } 81 for(i=0;i<n;i++) 82 { 83 int len = strlen(words[i]); 84 for(j=1;j<len;j++) 85 { 86 char t1[110],t2[110]; 87 CLR(t1,0);CLR(t2,0); 88 strncpy(t1,words[i],j); 89 strncpy(t2,words[i]+j,len-j); 90 if(Trie.Search(t1) && Trie.Search(t2)) 91 { 92 printf("%s\n",words[i]); 93 break; 94 } 95 } 96 } 97 return 0; 98 }
HDU 1251 统计难题
/* 几乎是裸的Trie,稍加改动统计方式即可 */
1 #include<cstdio> 2 #include<cstring> 3 #include<malloc.h> 4 using namespace std; 5 #define CLR(a,b) memset(a,b,sizeof(a)) 6 7 struct Trie 8 { 9 struct Node 10 { 11 Node* next[26]; 12 int cnt; 13 }; 14 15 Node* root; 16 17 void Init() 18 { 19 root = CreateNode(); 20 } 21 22 Node* CreateNode() 23 { 24 Node* tmp = (Node*)malloc(sizeof(Node)); 25 for(int i=0;i<26;i++) 26 tmp->next[i] = NULL; 27 tmp->cnt = 0; 28 return tmp; 29 } 30 31 void Insert(char* str) 32 { 33 Node* p = root; 34 while(*str) 35 { 36 int t = *str - 'a'; 37 if(p->next[t] == NULL) 38 p->next[t] = CreateNode(); 39 p = p->next[t]; 40 p->cnt++; 41 str++; 42 } 43 // p->cnt++; 44 } 45 46 int Search(char* str) 47 { 48 Node* p = root; 49 while(*str && p) 50 { 51 p = p->next[*str - 'a']; 52 str++; 53 } 54 if(p && p->cnt) 55 return p->cnt; 56 else 57 return 0; 58 } 59 60 void Delete(Node* rt) 61 { 62 if(rt == NULL) 63 return; 64 for(int i=0;i<26;i++) 65 { 66 if(rt->next[i]) 67 { 68 Delete(rt->next[i]); 69 } 70 } 71 free(rt); 72 } 73 }Trie; 74 75 76 char temp[1000000]; 77 78 int main() 79 { 80 Trie.Init(); 81 while(gets(temp),*temp) 82 { 83 Trie.Insert(temp); 84 } 85 while(~scanf("%s",temp)) 86 { 87 printf("%d\n",Trie.Search(temp)); 88 } 89 return 0; 90 }