• HDU 5687 Problem C 【字典树删除】


    传..传送: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(1N100000),代表度熊对于字典的操作次数,接下来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:

      1 #include <cstdio>
      2 #include <iostream>
      3 #include <algorithm>
      4 #include <cmath>
      5 #include <cstring>
      6 #define INF 0x3f3f3f3f
      7 #define LL long long int
      8 #define Bits 26
      9 using namespace std;
     10 const int MAXN = 33;
     11 int N;
     12 struct Trie
     13 {
     14     Trie *next[Bits];
     15     int flag;
     16     inline void init(){
     17         this->flag = 1;
     18         for(int i = 0; i < Bits; i++)
     19             this->next[i] = NULL;
     20     }
     21 };
     22 Trie *Root = (Trie *)malloc(sizeof(Trie));
     23 inline void DelTrie(Trie *t)
     24 {
     25     if(t == NULL) return;
     26     for(int i = 0; i < Bits; i++){
     27         if(t->next[i]!=NULL) DelTrie(t->next[i]);
     28     }free(t);
     29     return;
     30 }
     31 
     32 void Create_Trie(char *str, bool isDel)
     33 {
     34     int len = strlen(str);
     35     Trie *p = Root, *temp;
     36     int Delnum = 0;
     37     for(int i = 0; i < len; i++){
     38         int index = str[i]-'a';
     39         if(!isDel){
     40             if(p->next[index] == NULL){
     41                 temp = (Trie *)malloc(sizeof(Trie));
     42                 temp->init();
     43                 p->next[index] = temp;
     44                 p = p->next[index];
     45             }
     46             else{p->next[index]->flag+=1; p=p->next[index];}
     47         }
     48         else{
     49             if(p->next[index] != NULL){
     50                 Delnum = p->next[index]->flag;
     51                 p = p->next[index];
     52             }else return;
     53         }
     54     }
     55     if(isDel){
     56         p = Root;
     57         for(int i = 0; i < len; i++){
     58             int index = str[i]-'a';
     59             if(p->next[index] == NULL) return;
     60             if(i==len-1){
     61                 DelTrie(p->next[index]);
     62                 p->next[index] = NULL;
     63                 return;
     64             }
     65             p->next[index]->flag-=Delnum;
     66             p = p->next[index];
     67         }
     68     }
     69 }
     70 
     71 
     72 bool Find_Trie(char *str)
     73 {
     74     int len = strlen(str);
     75     Trie *p = Root;
     76     for(int i = 0; i < len; i++){
     77         int index = str[i]-'a';
     78         if(p->next[index] != NULL && p->next[index]->flag > 0)
     79             p=p->next[index];
     80         else return false;
     81     }return true;
     82 }
     83 
     84 int main()
     85 {
     86     Root->init();
     87     scanf("%d", &N);
     88     char str[MAXN], command[10];
     89     while(N--){
     90         scanf("%s", command);
     91         if(strcmp(command, "insert")==0){
     92             scanf("%s", str);
     93             Create_Trie(str, false);
     94         }
     95         else if(strcmp(command, "delete")==0){
     96             //puts("zjj");
     97             scanf("%s", str);
     98             Create_Trie(str, true);
     99         }
    100         else{
    101             scanf("%s", str);
    102             if(Find_Trie(str)) puts("Yes");
    103             else puts("No");
    104         }
    105     }DelTrie(Root);
    106     return 0;
    107 }
  • 相关阅读:
    测试的基本方法
    一些基本常用的正则表达式
    MySQL和Oracle的区别与不同
    Ubuntu中使用python3中的venv创建虚拟环境
    在Ubuntu中搭建Python3的虚拟环境并开始django项目
    Django中的图片加载不出来解决方式记录
    在django中进行后台管理时插入外键数据时不显示值的问题
    Django2.2连接mysql数据库出现django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.3 or newer is required; you have 0.7.11.None问题
    在Ubuntu中安装了MongoDB后无法启动mongod的问题
    PostgreSQL练习3
  • 原文地址:https://www.cnblogs.com/ymzjj/p/9553744.html
Copyright © 2020-2023  润新知