Problem C
Accepts: 630
Submissions: 5255
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 131072/131072 K (Java/Others)
Trie 字典树模拟
有几个提示
1.自己是自己的前缀
2.插入和删除的时候是单词 查找的时候是字符串
AC代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct Trie
{
//对应26个小写英文字母
Trie *word[26];
//计算次数
int time;
Trie()
{
time=0;
for(int i=0;i<26;i++)
word[i]=NULL;
}
};
//建树
void build(Trie *root,char *str)
{
for(str;*str;str++)
{
if(!root->word[*str-'a'])
{
root->word[*str-'a']=new Trie();
}
root->word[*str-'a']->time++;
root=root->word[*str-'a'];
}
}
//删除
void del(Trie *root,char *str)
{
Trie *head,*pre;
head=root;
int num,i;
for(i=0;str[i]!='\0';i++)
{
if(root->word[str[i]-'a'])
{
pre=root;
num=root->word[str[i]-'a']->time;
root=root->word[str[i]-'a'];
}
else
break;
}
if(str[i]=='\0')
{
//回收需要删除的节点
free(pre->word[str[i-1]-'a']);
//置为NULL 防止出现野指针
pre->word[str[i-1]-'a']=NULL;
for(int i=0;str[i]!='\0';i++)
{
if(head->word[str[i]-'a']!=NULL)
{
head->word[str[i]-'a']->time-=num;
head=head->word[str[i]-'a'];
}
}
}
}
//查找
bool search(Trie *root,char *str)
{
int i;
for(i=0;str[i]!='\0';i++)
{
if(root->word[str[i]-'a'])
root=root->word[str[i]-'a'];
else
break;
}
if(str[i]=='\0')
{
// 如果次数大于0 证明为单词的前缀
if(root->time>0)
return true;
}
return false;
}
int main()
{
int n;
Trie *root=new Trie();
scanf("%d",&n);
for(int i=0;i<n;i++)
{
char order[10];
char str[35];
scanf("%s %s",order,str);
if(strcmp(order,"insert")==0)
{
build(root,str);
}
if(strcmp(order,"delete")==0)
{
del(root,str);
}
if(strcmp(order,"search")==0)
{
if(search(root,str))
puts("Yes");
else
puts("No");
}
}
return 0;
}