zoukankan      html  css  js  c++  java
  • 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报错:java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone.
    MD5登陆密码的生成
    15. 3Sum、16. 3Sum Closest和18. 4Sum
    11. Container With Most Water
    8. String to Integer (atoi)
    6. ZigZag Conversion
    5. Longest Palindromic Substring
    几种非线性激活函数介绍
    AI初探1
    AI初探
  • 原文地址:https://www.cnblogs.com/ymzjj/p/9553744.html
Copyright © 2011-2022 走看看