度熊手上有一本神奇的字典,你可以在它里面做如下三个操作:
1、insert : 往神奇字典中插入一个单词
2、delete: 在神奇字典中删除所有前缀等于给定字符串的单词
3、search: 查询是否在神奇字典中有一个字符串的前缀等于给定的字符串
Input
这里仅有一组测试数据。第一行输入一个正整数N(1≤N≤100000)N(1≤N≤100000),代表度熊对于字典的操作次数,接下来NN行,每行包含两个字符串,中间中用空格隔开。第一个字符串代表了相关的操作(包括: 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
在添加一个单词时,针对在字典树中这个单词经过的所有节点,都会flag+1,表示有多少单词经过它。
在删除一个单词时,先统计出这个单词出现的次数。然后在遍历节点时这个单词经过的所有节点都要减去这个次数。
注意递归删除和添加字典树的写法。
#include<string.h>
#include<stdio.h>
#include<malloc.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 26;
struct Trie
{
Trie *Next[maxn];
int flag;
inline void init()
{
this->flag=1;
for(int i=0; i<maxn; i++)
{
this->Next[i]=NULL;
}
}
};
Trie *root =(Trie*)malloc(sizeof(Trie));
inline void DelTrie(Trie * T)
{
if(T==NULL)
return ;
for(int i=0; i<maxn; i++)
{
if(T->Next[i]!=NULL)
{
DelTrie(T->Next[i]);//递归删除节点
}
}
free(T);
return;
}
void createTrie(char *str,bool isDel)
{
int len=strlen(str);//str是一个数组
Trie *p=root,*temp;
int DelNum=0;
for(int i=0; i<len; i++)
{
int idx=str[i]-'a';
if(!isDel)
{
if(p->Next[idx]==NULL)
{
temp=(Trie *)malloc(sizeof(Trie));
temp->init();
p->Next[idx]=temp;
p=p->Next[idx];
}
else
{
p->Next[idx]->flag++;
p=p->Next[idx];
}
}
else
{
if(p->Next[idx]!=NULL)
{
DelNum=p->Next[idx]->flag;
p=p->Next[idx];
}
else
{
return ;
}
}
}
if(isDel)
{
p=root;//删除情况
for(int i=0; i<len; i++)
{
int idx=str[i]-'a';
if(p->Next[idx]==NULL)
return;
if(i==len-1)
{
//终点
DelTrie(p->Next[idx]);
p->Next[idx]=NULL;//递归删除
return ;
}
p->Next[idx]->flag-=DelNum;
p=p->Next[idx];
}
}
}
bool FindStr(char *str)
{
int len=strlen(str);
Trie *p=root;
for(int i=0; i<len; i++)
{
int idx=str[i]-'a';
if(p->Next[idx]!=NULL&&p->Next[idx]->flag>0)
p=p->Next[idx];
else
return false;
}
return true;
}
int main(void)
{
root->init();
int n;
scanf("%d", &n);
char command[7], str[33];
while(n--)
{
scanf("%s", command);
if(strcmp(command, "insert")==0)
{
scanf("%s", str);
createTrie(str, false);
}
else if(strcmp(command, "delete")==0)
{
scanf("%s", str);
createTrie(str, true);//删除的时候
}
else
{
scanf("%s", str);
FindStr(str)?puts("Yes"):puts("No");
}
}
DelTrie(root);
return 0;
}