HDU - 5687——Problem C

6 篇文章 0 订阅

Problem C

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


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


字典树

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
class Trie {
private:
    Trie *next[26];
    int vju;
public:
    Trie() {
        vju=0;
        for(int i=0; i<26; i++)
            next[i]=NULL;
    }
    void insert(const char *a,int i=0) {
        if(!next[a[i]-97]) next[a[i]-97]=new Trie;
        if(!a[i+1]) {
            next[a[i]-97]->vju=1;
            return;
        }
        next[a[i]-97]->insert(a,i+1);
    }
    bool Prefix_cmp(const char *a,int i=0) {
        if(!next[a[i]-97]) return false;
        if(!a[i+1]) return true;
        return next[a[i]-97]->Prefix_cmp(a,i+1);
    }
    void pop(int L,int R=0) {
        if(!R) R=L+1;
        for(int i=L; i<R; i++)
            if(next[i]) {
                next[i]->pop(0,26);
                delete next[i];
                next[i]=NULL;
            }
    }
    bool check_end(const Trie *a) {
        for(int i=0; i<26; i++)
            if(a->next[i])
                return true;
        return false;
    }
    bool pop(const char *a,int i=0) {
        if(!i&&!Prefix_cmp(a)) return false;
        if(!a[i+1]) {
            pop(a[i]-97);
            return true;
        }
        if(next[a[i]-97]->pop(a,i+1)) {
            if(next[a[i]-97]->vju||check_end(next[a[i]-97])) return false;
            pop(a[i]-97);
            return true;
        }
        return false;
    }
    void show(int j=0) {
        cout<<j<<"___";
        for(int i=0; i<26; i++)
            if(next[i])
                cout<<char(i+97)<<' '<<next[i]->vju;
        cout<<endl;
        for(int i=0; i<26; i++)
            if(next[i])
                next[i]->show(j+1);
    }
};
int main() {
    int n;
    cin>>n;
    Trie t;
    char a[10],b[36];
    while(n--) {
        cin>>a>>b;
        if(!strcmp(a,"insert"))
            t.insert(b);
        else if(!strcmp(a,"delete"))
            t.pop(b);
        else if(t.Prefix_cmp(b))
            cout<<"Yes"<<endl;
        else cout<<"No"<<endl;
         // t.show();
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值