传..传送:http://acm.hdu.edu.cn/showproblem.php?pid=5687

Problem C

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 2697    Accepted Submission(s): 743

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
 
Source
 

解题思路:

输入查询都是字典树基本操作,这里的字典树的删除是一种标记删除而不是物理删除(非最后节点)。

但是这里的标记删除要注意的是不能直接取消标记或标记为 0 ,而是要根据要删除的字符串在字典中出现的次数,然后根据这个次数去更新路径上的点的标记。如果是删除字符的最后节点则进行物理删除。

例如说:字典里是 zzaizjja,zzaizjj,要删除 zzaizjja,如果单纯把路径 zzaizjja 上的节点都更新为0,则它的子串也 out 了,所以正确的更新是:路径上的点减去zzaizjja出现的次数。

AC Code:

 #include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#define INF 0x3f3f3f3f
#define LL long long int
#define Bits 26
using namespace std;
const int MAXN = ;
int N;
struct Trie
{
Trie *next[Bits];
int flag;
inline void init(){
this->flag = ;
for(int i = ; i < Bits; i++)
this->next[i] = NULL;
}
};
Trie *Root = (Trie *)malloc(sizeof(Trie));
inline void DelTrie(Trie *t)
{
if(t == NULL) return;
for(int i = ; i < Bits; i++){
if(t->next[i]!=NULL) DelTrie(t->next[i]);
}free(t);
return;
} void Create_Trie(char *str, bool isDel)
{
int len = strlen(str);
Trie *p = Root, *temp;
int Delnum = ;
for(int i = ; i < len; i++){
int index = str[i]-'a';
if(!isDel){
if(p->next[index] == NULL){
temp = (Trie *)malloc(sizeof(Trie));
temp->init();
p->next[index] = temp;
p = p->next[index];
}
else{p->next[index]->flag+=; p=p->next[index];}
}
else{
if(p->next[index] != NULL){
Delnum = p->next[index]->flag;
p = p->next[index];
}else return;
}
}
if(isDel){
p = Root;
for(int i = ; i < len; i++){
int index = str[i]-'a';
if(p->next[index] == NULL) return;
if(i==len-){
DelTrie(p->next[index]);
p->next[index] = NULL;
return;
}
p->next[index]->flag-=Delnum;
p = p->next[index];
}
}
} bool Find_Trie(char *str)
{
int len = strlen(str);
Trie *p = Root;
for(int i = ; i < len; i++){
int index = str[i]-'a';
if(p->next[index] != NULL && p->next[index]->flag > )
p=p->next[index];
else return false;
}return true;
} int main()
{
Root->init();
scanf("%d", &N);
char str[MAXN], command[];
while(N--){
scanf("%s", command);
if(strcmp(command, "insert")==){
scanf("%s", str);
Create_Trie(str, false);
}
else if(strcmp(command, "delete")==){
//puts("zjj");
scanf("%s", str);
Create_Trie(str, true);
}
else{
scanf("%s", str);
if(Find_Trie(str)) puts("Yes");
else puts("No");
}
}DelTrie(Root);
return ;
}

最新文章

  1. Sqlite3常用的插入方法及性能测试
  2. css3 背景渐变
  3. Redis应用场景一
  4. Codrops 教程:实现内容倾斜的 3D 幻灯片效果
  5. kuangbin_ShortPath I (POJ 2240)
  6. select,epool,pool解释
  7. Java各种类型占用的字节数
  8. Hbase对hive的支持没有hdfs的好的原因 及hbase什么时候使用 及rowkey设计技巧
  9. golang中channel的超时处理
  10. 【转】使用Boost Graph library(二)
  11. cocos2d-x lua 内存回收
  12. YARN简短的建筑
  13. android奋战的一周
  14. 学问Chat UI(2)
  15. Java安全套接字扩展——JSSE
  16. tab页的使用方法
  17. oracle使用数据泵进行数据的导入导出
  18. Shellcode入门
  19. hdu 4513 最长不下降回文序列【manacher】
  20. linux 下 nginx的负载均衡

热门文章

  1. oracle 基础知识(二)-表空间
  2. 对象池3(方法功能)PoolManager(控制)PoolTimeObject(时间管理)text01(调用)Destorys(销毁)
  3. 接口隔离原则(Interface Segregation Principle)ISP
  4. unity项目架构
  5. WPF 窗体在Alt+Tab中隐藏
  6. 电影:换肤(Replace)
  7. java程序: 倒计时的小程序 (GridPane, Timer, Calendar, SimpleDateFormat ...)
  8. 【Spring Cloud】与Spring Boot版本匹配关系
  9. JavaSE环境Shiro的搭建及常用API
  10. CSS 面包屑导航栏