[HDU5687]2016"百度之星"

题目大意:有n个操作,每个操作是以下三个之一,要你实现这些操作。

1、insert : 往字典中插入一个单词
2、delete: 在字典中删除所有前缀等于给定字符串的单词
3、search: 查询是否在字典中有一个字符串的前缀等于给定的字符串

解题思路:Trie树即可。

注意代码第49行的判断,我当时以为只要成功搜到这个前缀就一定有答案,忽略了删除操作使某些前缀的单词数为0的情况。

C++ Code:

#include<cstdio>
struct node{
	int cnt;
	node* nxt[27];
	node():cnt(0){for(int i=0;i<26;++i)nxt[i]=NULL;}
}*d;
char s[40];
void ins(char* s){
	++d->cnt;
	node *now=d;
	for(int i=0;s[i];++i){
		int v=s[i]-'a';
		if(now->nxt[v]==NULL)now->nxt[v]=new node;
		now=now->nxt[v];
		++now->cnt;
	}
}
void clear(node* p){
	for(int i=0;i<26;++i)
	if(p->nxt[i]!=NULL)clear(p->nxt[i]);
	delete p;
}
void del(char* s){
	node* p=d,*pre=p;
	int v;
	for(int i=0;s[i];++i){
		v=s[i]-'a';
		if(p->nxt[v]==NULL)return;
		pre=p;
		p=p->nxt[v];
	}
	int num=p->cnt;
	clear(p);
	pre->nxt[v]=NULL;
	p=d;
	for(int i=0;;++i){
		p=p->nxt[s[i]-'a'];
		if(p==NULL)break;
		p->cnt-=num;
	}
}
bool ask(char* s){
	node* p=d;
	for(int i=0;s[i];++i){
		int v=s[i]-'a';
		p=p->nxt[v];
		if(p==NULL)return false;
	}
	if(p->cnt<1)return false;
	return true;
}
int main(){
	d=new node;
	int n;
	scanf("%d",&n);
	while(n--){
		scanf("%s",s);
		if(s[0]=='i'){
			scanf("%s",s);
			ins(s);
		}else
		if(s[0]=='d'){
			scanf("%s",s);
			del(s);
		}else{
			scanf("%s",s);
			if(ask(s))puts("Yes");else
			puts("No");
		}
	}
	return 0;
}
原文地址:https://www.cnblogs.com/Mrsrz/p/7365372.html