Phone List
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 6772 Accepted Submission(s): 2307
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 typedef struct _TrieTree 6 { 7 bool flag; 8 struct _TrieTree *next[10]; 9 10 }TrieNode; 11 12 TrieNode *CreateTrieTree() //创建字典树 13 { 14 TrieNode *node = (TrieNode *)malloc(sizeof(TrieNode)); 15 node->flag = false; 16 for(int i = 0; i < 10; i++) 17 node->next[i] = NULL; 18 19 return node; 20 } 21 22 void InsertTrieTree(TrieNode *root, char word[]) //插入字符串 23 { 24 TrieNode *p = root; 25 int length = strlen(word); 26 for(int i = 0; i < length; i++) 27 { 28 int index = word[i] - 48; 29 if(p->next[index] == NULL) 30 { 31 p->next[index] = CreateTrieTree(); 32 } 33 p = p->next[index]; 34 } 35 p->flag = true; 36 } 37 38 bool QueryTrieTree(TrieNode *root, char word[]) //查询字符串 39 { 40 TrieNode *p = root; 41 int length = strlen(word); 42 for(int i = 0; i < length; i++) 43 { 44 int index = word[i] - 48; 45 p = p->next[index]; 46 if(i != length - 1 && p->flag) 47 return false; 48 } 49 50 return true; 51 } 52 53 void FreeTrieTree(TrieNode *root) //递归释放每个字典树的内存 54 { 55 TrieNode *p = root; 56 if(p != NULL) 57 { 58 for(int i = 0; i < 10; i++) 59 { 60 if(p->next[i] != NULL) 61 FreeTrieTree(p->next[i]); 62 } 63 delete p; 64 p = NULL; 65 } 66 } 67 68 int main() 69 { 70 int T, n; 71 const int MAX_NUM = 10005; 72 char word[MAX_NUM][11]; 73 74 scanf("%d", &T); 75 while(T--) 76 { 77 TrieNode *root = CreateTrieTree(); 78 79 scanf("%d", &n); 80 getchar(); 81 for(int i = 0; i < n; i++) 82 { 83 scanf("%s", word[i]); 84 InsertTrieTree(root, word[i]); 85 } 86 87 bool bResult = true; 88 for(int i = 0; i < n; i++) 89 { 90 bResult = QueryTrieTree(root, word[i]); 91 if(!bResult) 92 break; 93 } 94 95 if(bResult) 96 printf("YES\n"); 97 else 98 printf("NO\n"); 99 100 FreeTrieTree(root); 101 } 102 103 return 0; 104 }
然后,看到网上有的是在插入的过程中进行判断的,若在插入的过程中就已经判断出来有不符合条件的前缀字符串,
则剩余的未输入的字符串就不再插入到字典树中,减少部分时间开销。
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 typedef struct _TrieTree 6 { 7 bool flag; 8 struct _TrieTree *next[10]; 9 10 }TrieNode; 11 12 TrieNode *CreateTrieTree() //创建字典树 13 { 14 TrieNode *node = (TrieNode *)malloc(sizeof(TrieNode)); 15 node->flag = false; 16 for(int i = 0; i < 10; i++) 17 node->next[i] = NULL; 18 19 return node; 20 } 21 22 bool InsertTrieTree(TrieNode *root, char word[]) //插入字符串 23 { 24 TrieNode *p = root; 25 int length = strlen(word); 26 for(int i = 0; i < length; i++) 27 { 28 int index = word[i] - 48; 29 if(p->next[index] == NULL) 30 { 31 p->next[index] = CreateTrieTree(); 32 } 33 p = p->next[index]; 34 if(p->flag) //有字符串是它的前缀 35 return false; 36 } 37 for(int i = 0; i < 10; i++) 38 if(p->next[i] != NULL) //它是别的字符串的前缀 39 return false; 40 41 p->flag = true; 42 return true; 43 } 44 45 void FreeTrieTree(TrieNode *root) //递归释放每个字典树的内存 46 { 47 TrieNode *p = root; 48 if(p != NULL) 49 { 50 for(int i = 0; i < 10; i++) 51 { 52 if(p->next[i] != NULL) 53 FreeTrieTree(p->next[i]); 54 } 55 free(p); 56 p = NULL; 57 } 58 } 59 60 int main() 61 { 62 int T, n; 63 const int MAX_NUM = 10005; 64 char word[MAX_NUM][11]; 65 66 scanf("%d", &T); 67 while(T--) 68 { 69 TrieNode *root = CreateTrieTree(); 70 71 bool bResult = true; 72 scanf("%d", &n); 73 getchar(); 74 for(int i = 0; i < n; i++) 75 { 76 scanf("%s", word[i]); 77 if(!bResult) //若插入的过程中,已判断不符合条件 78 continue; //就跳过,不再插入 79 if(!InsertTrieTree(root, word[i])) 80 bResult = false; 81 } 82 83 if(bResult) 84 printf("YES\n"); 85 else 86 printf("NO\n"); 87 88 FreeTrieTree(root); 89 } 90 91 return 0; 92 }
另外还有一种方法,先对所有字符串进行排序,然后比较相邻两个字符串,若前一个字符串是后一个字符串的前缀,
就输出NO,否则输出YES。
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 5 typedef struct _PHONE 6 { 7 char word[11]; 8 9 }PHONE; 10 11 int cmp(const void *a, const void *b) 12 { 13 return strcmp( (*(PHONE *)a).word, (*(PHONE *)b).word ); 14 } 15 16 int main() 17 { 18 int T, n; 19 const int MAX_NUM = 10005; 20 PHONE phone[MAX_NUM]; 21 22 scanf("%d", &T); 23 while(T--) 24 { 25 scanf("%d", &n); 26 for(int i = 0; i < n; i++) 27 scanf("%s", phone[i].word); 28 29 qsort(phone, n, sizeof(PHONE), cmp); 30 31 bool bResult = true; 32 for(int i = 0; i < n - 1; i++) 33 { 34 char *p = strstr(phone[i + 1].word, phone[i].word); 35 if(p != NULL) 36 { 37 bResult = false; 38 break; 39 } 40 } 41 if(bResult) 42 printf("YES\n"); 43 else 44 printf("NO\n"); 45 } 46 47 return 0; 48 }