2016-百度之星-资格赛-Problem C【字典树】
2016-05-17 17:21
387 查看
Problem Description
度熊手上有一本神奇的字典,你可以在它里面做如下三个操作:
1、insert : 往神奇字典中插入一个单词
2、delete: 在神奇字典中删除所有前缀等于给定字符串的单词
3、search: 查询是否在神奇字典中有一个字符串的前缀等于给定的字符串
Input
这里仅有一组测试数据。第一行输入一个正整数N(1≤N≤100000),代表度熊对于字典的操作次数,接下来N行,每行包含两个字符串,中间中用空格隔开。第一个字符串代表了相关的操作(包括: 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
题目思路:这是一道很经典的字典树问题,涉及到插入删除查找操作。
删除:删除“abc”,则删除所有前缀为abc的单词。
注意点1:
insert hello
insert hehe
delete hel
search he //yes
—>删除的是前缀为hel的,hehe前缀为he,所以无影响
注意点2:
insert hello
delete hel
insert hel
search hello //no
—>删除了hel,即删除了hello这个单词。重新插入的时候是不存在hello
所以:在写删除操作的时候需要注意,找到了hel的l所在节点,记录hel出现的次数num,那么这个单词这条路上都需要减去num
注意点3:
在删除的时候需要判断下一个节点是否存在,不然会RE
以下是代码:
度熊手上有一本神奇的字典,你可以在它里面做如下三个操作:
1、insert : 往神奇字典中插入一个单词
2、delete: 在神奇字典中删除所有前缀等于给定字符串的单词
3、search: 查询是否在神奇字典中有一个字符串的前缀等于给定的字符串
Input
这里仅有一组测试数据。第一行输入一个正整数N(1≤N≤100000),代表度熊对于字典的操作次数,接下来N行,每行包含两个字符串,中间中用空格隔开。第一个字符串代表了相关的操作(包括: 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
题目思路:这是一道很经典的字典树问题,涉及到插入删除查找操作。
删除:删除“abc”,则删除所有前缀为abc的单词。
注意点1:
insert hello
insert hehe
delete hel
search he //yes
—>删除的是前缀为hel的,hehe前缀为he,所以无影响
注意点2:
insert hello
delete hel
insert hel
search hello //no
—>删除了hel,即删除了hello这个单词。重新插入的时候是不存在hello
所以:在写删除操作的时候需要注意,找到了hel的l所在节点,记录hel出现的次数num,那么这个单词这条路上都需要减去num
注意点3:
在删除的时候需要判断下一个节点是否存在,不然会RE
以下是代码:
// // 百度之星-资格赛C.cpp // practice // // Created by pro on 16/5/14. // Copyright (c) 2016年 loy. All rights reserved. // #include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #include <functional> #include <numeric> #include <sstream> #include <stack> #include <map> #include <queue> #include<iomanip> using namespace std; struct node { int cnt; node *next[26]; void init() //初始化 { cnt=0; for(int i=0;i<26;i++) { next[i]=NULL; } } } ; void insert(node *root,char *s) { node *p=root; for(int i=0;s[i];i++) { int t=s[i]-'a'; if(p->next[t]==NULL) { p->next[t]=new node; p=p->next[t]; p->init() ; } else p=p->next[t]; p->cnt++; } } void Delete(node *root,char *s) { node *p = root; node *pre = root; node *head = root; int t,i,num = 0; for(i=0; s[i]; i++) { t=s[i]-'a'; if(p->next[t]!=NULL) { pre = p; num = p->next[t]->cnt; p=p->next[t]; } else { break; } } if(s[i] == '\0') { free(pre->next[s[i - 1] - 'a']); pre->next[s[i - 1] - 'a'] = NULL; for (int j = 0; s[j]; j++) { int t = s[j] - 'a'; if (head->next[t] != NULL) { head->next[t]->cnt -= num; head = head->next[t]; } } } } int find(node *root, char *s) { node *p=root; for(int i=0;s[i];i++) { int t=s[i]-'a'; p=p->next[t]; if(!p) return 0; } if (p->cnt) return 1; else return 0; } int main() { node *root=new node(); root->init(); int n; cin >> n; while(n--) { char a[10],b[35]; scanf("%s",a); scanf("%s",b); if (strcmp(a,"insert") == 0) { insert(root,b); } else if (strcmp(a,"delete") == 0) { Delete(root,b); } else { int ans = find(root,b); if (ans) cout << "Yes\n"; else cout << "No\n"; } } return 0; }
相关文章推荐
- Unreal Cook Book:动态改变材质的颜色等参数
- 高效排序算法(希尔排序)
- 高效排序算法(快排序)
- 零编程开发管理软件,提高效率,缩短开发周期
- php+nginx搭建
- 朴素贝叶斯分类
- Android Studio项目结构&AS构建基础
- Json Web Token身份认证
- 【数据库】基础知识总结
- Codeforces Round #353 (Div. 2)题解
- 【转】SIFT特征提取分析
- [转]如何成为主管
- mate 8、荣耀6,手机连接eclipse、AS调试应用没有log输出
- JavaScript字符串处理函数 - split()、join()、substring()和indexOf()
- AndroidTV桌面BriskTVLanucher
- 二叉查找树(AVL)插入算法Java实现
- Android中进程和线程
- 一个简单的递归算法的思考
- hibernate相关问题
- 可能最有效的母亲节邮件主题,你用对了吗?