字典树 - 神奇的字典
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 (!Search