字典树 - 神奇的字典
Description
度熊手上有一本神奇的字典,你可以在它里面做如下三个操作:
1、insert : 往神奇字典中插入一个单词
2、delete: 在神奇字典中删除所有前缀等于给定字符串的单词
3、search: 查询是否在神奇字典中有一个字符串的前缀等于给定的字符串
1、insert : 往神奇字典中插入一个单词
2、delete: 在神奇字典中删除所有前缀等于给定字符串的单词
3、search: 查询是否在神奇字典中有一个字符串的前缀等于给定的字符串
Input
这里仅有一组测试数据。第一行输入一个正整数N (1 <= N <= 100000),代表度熊对于字典的操作次数,接下来N行,每行包含两个字符串,中间中用空格隔开。第一个字符串代表了相关的操作(包括: insert, delete 或者 search)。第二个字符串代表了相关操作后指定的那个字符串,第二个字符串的长度不会超过30。第二个字符串仅由小写字母组成。
Output
对于每一个search 操作,如果在度熊的字典中存在给定的字符串为前缀的单词,则输出Yes 否则输出 No。
Sample Input
5
insert hello
insert hehe
search h
delete he
search hello
Sample Output
Yes
No
很迷的一道题,我用指针指了两个小时,终于在混乱中理清了头绪,指针果然还是少用为好,好凌乱啊= =
除了删除是我搞了很久的之外,其他的应该都不难,不然就去看看字典树的模板,其实我这个就是模板,嘻嘻
#include<cstdio>
#include<algorithm>
#include<cstring> #include<string> #include<queue> #include<cstdlib> using namespace std; struct Trie { int v; Trie *next[26]; }; int rec;//用来记录每一次查询存在且以此为前缀的单词的个数 Trie root, *trie, *newtrie; void Insert(char str[]) { int len = strlen(str); trie = &root; for (int i = 0; i < len; i++) { int id = str[i] - 'a'; if (trie -> next[id] == NULL) { newtrie = (Trie*)malloc(sizeof(Trie)); for (int i = 0; i < 26; i++) newtrie -> next[i] = NULL; trie -> next[id] = newtrie; trie -> next[id] -> v = 1; trie = trie -> next[id]; } else { trie -> next[id] -> v ++; trie = trie -> next[id]; } } } bool Search(char str[]) { rec = 0; int len = strlen(str); trie = &root; for (int i = 0; i < len; i++) { int id = str[i] - 'a'; if (trie -> next[id] == NULL) return false; else trie = trie -> next[id]; } rec = trie -> v; return true; } void DeleteAll(Trie *t) { for (int i = 0; i < 26; i++) { if (t -> next[i] != NULL) { Trie *t1 = t -> next[i]; DeleteAll(t1); } } free(t); } void Delete(char str[]) { if