2016-百度之星-资格赛-Problem C【字典树】

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

题目思路:这是一道很经典的字典树问题,涉及到插入删除查找操作。

删除:删除“abc”,则删除所有前缀为abc的单词。

注意点1:

insert hello
insert hehe
delete hel
search he //yes

—>删除的是前缀为hel的,hehe前缀为he,所以无影响

注意点2:

insert hello
delete hel
insert hel
search hello //no

—>删除了hel,即删除了hello这个单词。重新插入的时候是不存在hello

所以:在写删除操作的时候需要注意,找到了hel的l所在节点,记录hel出现的次数num,那么这个单词这条路上都需要减去num

注意点3:

在删除的时候需要判断下一个节点是否存在,不然会RE

以下是代码:

//
// 百度之星-资格赛C.cpp
// practice
//
// Created by pro on 16/5/14.
// Copyright (c) 2016年 loy. All rights reserved.
//

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>
#include<iomanip>
using namespace std;
struct node
{
    int cnt;
    node *next[26];
    void init() //初始化
    {
        cnt=0;
        for(int i=0;i<26;i++)
        {
            next[i]=NULL;
        }
    }
} ;

void insert(node *root,char *s)
{
    node *p=root;
    for(int i=0;s[i];i++)
    {
        int t=s[i]-'a';
        if(p->next[t]==NULL)
        {
            p->next[t]=new node;
            p=p->next[t];
            p->init() ;
        }
        else
            p=p->next[t];
        p->cnt++;
    }
}
void Delete(node *root,char *s)
{
    node *p = root;
    node *pre = root;
    node *head = root;
    int t,i,num = 0;
    for(i=0; s[i]; i++)
    {
        t=s[i]-'a';
        if(p->next[t]!=NULL)
        {
            pre = p;
            num = p->next[t]->cnt;
            p=p->next[t];
        }
        else
        {
            break;
        }
    }
    if(s[i] == '\0')
    {
        free(pre->next[s[i - 1] - 'a']);
        pre->next[s[i - 1] - 'a'] = NULL;
        for (int j = 0; s[j]; j++)
        {
            int t = s[j] - 'a';
            if (head->next[t] != NULL)
            {
                head->next[t]->cnt -= num;
                head = head->next[t];
            }
        }
    }

}
int find(node *root, char *s)
{
    node *p=root;
    for(int i=0;s[i];i++)
    {
        int t=s[i]-'a';
        p=p->next[t];
        if(!p) return 0;
    }
    if (p->cnt) return 1;
    else return 0;
}

int main()
{
    node *root=new node();
    root->init();
    int n;
    cin >> n;
    while(n--)
    {
        char a[10],b[35];
        scanf("%s",a);
        scanf("%s",b);
        if (strcmp(a,"insert") == 0)
        {
            insert(root,b);
        }
        else if (strcmp(a,"delete") == 0)
        {
            Delete(root,b);
        }
        else
        {
            int ans = find(root,b);
            if (ans) cout << "Yes\n";
            else cout << "No\n";
        }
    }
    return 0;
}

你可能感兴趣的:(百度之星,字典树)