zoukankan      html  css  js  c++  java
  • HDU 5687 Problem C ( 字典树前缀增删查 )

    题意 : 度熊手上有一本神奇的字典,你可以在它里面做如下三个操作:

    1、insert : 往神奇字典中插入一个单词

    2、delete: 在神奇字典中删除所有前缀等于给定字符串的单词

    3、search: 查询是否在神奇字典中有一个字符串的前缀等于给定的字符串

     

    分析 : 利用字典树,插入操作时对于每一个节点的标记权值+1,代表此前缀+1,然后删除操作的时候尤为要注意的就是对于给出的前缀,不能在字典树上将权值置为0,因为如果现在假设已经插入了 abc、ab 现在要求 delete abc 则不能将 ab 这个前缀的标记权值变成 0 ,这很显然是不对的( 虽然自己傻逼被坑了=_= ),正确的做法是找到 abc 在字典树出现的次数,然后再从 root 节点将 abc 这个前缀途经的节点减去这个次数,最后面对 abc 后面的节点 free 掉即可

    #include<string.h>
    #include<stdio.h>
    #include<malloc.h>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int maxn = 26;
    
    struct Trie
    {
        Trie *Next[maxn];
        int flag;
        inline void init(){
            this->flag = 1;
            for(int i=0; i<maxn; i++)
                this->Next[i] = NULL;
        }
    };
    Trie *root = (Trie *)malloc(sizeof(Trie));
    
    inline void DelTrie(Trie *T)
    {
        if(T == NULL) return ;
        for(int i=0; i<maxn; i++){
            if(T->Next[i] != NULL)
                DelTrie(T->Next[i]);
        } free(T);
        return ;
    }
    
    void CreateTrie(char *str, bool isDel)
    {
        int len = strlen(str);
        Trie *p = root, *tmp;
        int DelNum = 0;
        for(int i=0; i<len; i++){
            int idx = str[i]-'a';
            if(!isDel){
                if(p->Next[idx] == NULL){
                    tmp = (Trie *)malloc(sizeof(Trie));
                    tmp->init();
                    p->Next[idx] = tmp;
                    p = p->Next[idx];
                }else { p->Next[idx]->flag += 1; p = p->Next[idx]; }
            }else{
                if(p->Next[idx] != NULL){
                    DelNum = p->Next[idx]->flag;
                    p = p->Next[idx];
                }else return ;
            }
        }
        if(isDel){
            p = root;
            for(int i=0; i<len; i++){
                int idx = str[i] - 'a';
                if(p->Next[idx] == NULL) return ;
                if(i == len-1){
                   DelTrie(p->Next[idx]);
                   p->Next[idx] = NULL;
                   return ;
                }
                p->Next[idx]->flag -= DelNum;
                p = p->Next[idx];
            }
        }
    }
    
    bool FindTrie(char *str)
    {
        int len = strlen(str);
        Trie *p = root;
        for(int i=0; i<len; i++){
            int idx = str[i]-'a';
            if(p->Next[idx] != NULL && p->Next[idx]->flag > 0) p = p->Next[idx];
            else return false;
        }return true;
    }
    
    
    
    int main(void)
    {
        root->init();
        int n;
        scanf("%d", &n);
        char command[7], str[33];
        while(n--){
            scanf("%s", command);
            if(strcmp(command, "insert")==0){
                scanf("%s", str);
                CreateTrie(str, false);
            }
            else if(strcmp(command, "delete")==0){
                scanf("%s", str);
                CreateTrie(str, true);
            }
            else{
                scanf("%s", str);
                FindTrie(str)?puts("Yes"):puts("No");
            }
        }DelTrie(root);
        return 0;
    }
    View Code

    瞎 : 要冷静分析啊!字典树上是怎么在跑的,还有内存问题啊!很裸的字典树写不出来就傻逼了!

  • 相关阅读:
    VBA通配符(*, ?, ~)
    pycharm更换包下载镜像
    python在使用pip安装模块的时候下载速度很慢的问题
    java标识符
    C语言||作业01 结构:通讯录
    C语言寒假大作战04
    C语言寒假大作战03
    C语言寒假大作战02
    c语言寒假大作战
    C语言I作业12—学期总结
  • 原文地址:https://www.cnblogs.com/qwertiLH/p/7613943.html
Copyright © 2011-2022 走看看