题目大意:有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);}elseif(s[0]=='d'){scanf("%s",s);del(s);}else{scanf("%s",s);if(ask(s))puts("Yes");elseputs("No");}}return 0;
}