Problem C (字典树的查找删除和插入)2016"百度之星" - 资格赛(Astar Round1)

Problem C

 
 Accepts: 630
 
 Submissions: 5255
 Time Limit: 2000/1000 MS (Java/Others)
 
 Memory Limit: 131072/131072 K (Java/Others)
Problem Description

度熊手上有一本神奇的字典,你可以在它里面做如下三个操作:

1、insert : 往神奇字典中插入一个单词

2、delete: 在神奇字典中删除所有前缀等于给定字符串的单词

3、search: 查询是否在神奇字典中有一个字符串的前缀等于给定的字符串
Input

这里仅有一组测试数据。第一行输入一个正整数N (1\leq N\leq 100000)N(1N100000),代表度熊对于字典的操作次数,接下来NN行,每行包含两个字符串,中间中用空格隔开。第一个字符串代表了相关的操作(包括: insert, delete 或者 search)。第二个字符串代表了相关操作后指定的那个字符串,第二个字符串的长度不会超过30。第二个字符串仅由小写字母组成。

Output

对于每一个search 操作,如果在度熊的字典中存在给定的字符串为前缀的单词,则输出Yes 否则输出 No。

Sample Input
5
insert hello
insert hehe
search h
delete he
search hello
Sample Output
Copy
Yes
No

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;
}



你可能感兴趣的:(Trie字典树,前缀树的查找删除和插入)