码迷,mamicode.com
首页 > 其他好文 > 详细

2016"百度之星" - 资格赛(Astar Round1) Problem C (Trie树)

时间:2016-05-16 09:23:36      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:

题意:对单词根据前缀进行插入,插入,和查询操作,查询的话存在即可。

因为之前几乎没怎么做过类似的题,再加上这次做的时候,对题意理解的不到位,所以错了很多次,以后要先把题意理解透彻再敲代码,这样会避开之后修改的很多不必要的细节错误。

思路:Trie树,root根节点通过next指针数组连接着26个相同的结点,分别代表26个英文字母,对应着第一个字母,同理,之后的字母也这么建立。这样树形结构就出来了。结构体里的num为记录以当前字符串为前缀的单词的数目。

(1)insertNode:插入单词,如果之前这样的前缀并不存在,为其分配结点即可,如果已经存在,计数器 + 1。

(2)delNode:删除单词,找到对应的前缀之后,使其计数器清零,或者删除节点都行,*但是删除之前应该记录计数器的数值,因为删除了以此为前缀的单词,前面的前缀对应的计数器也应该减少(全局变量temp就是用来记录这个值的,以便于之后的操作中使之前的前缀减去这个值)*因为这个错了很多次QAQ。

(3)delNum:有delNode删除完单词之后调用,使这个单词之前的前缀对应的num值同样减少temp。

eg:删除了以abc为前缀的单词 2 个,temp为 2,那么分别以a, b为前缀的单词数目同样减少temp。

(4)searchNode:查询操作,找到以str2数组为前缀的num值,如果其>0,即输出"Yes",反之,"No"。

 

Problem Description

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

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

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

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

Input

这里仅有一组测试数据。第一行输入一个正整数N(1≤N≤100000)N (1\leq N\leq 100000)N(1≤N≤100000),代表度熊对于字典的操作次数,接下来NNN行,每行包含两个字符串,中间中用空格隔开。第一个字符串代表了相关的操作(包括: insert, delete 或者 search)。第二个字符串代表了相关操作后指定的那个字符串,第二个字符串的长度不会超过30。第二个字符串仅由小写字母组成。

Output

对于每一个search 操作,如果在度熊的字典中存在给定的字符串为前缀的单词,则输出Yes 否则输出 No。

Sample Input

Copy

5
insert hello
insert hehe
search h
delete he
search hello

Sample Output

Copy

Yes
No
贴上代码(这是比赛时候改了很多次的代码,写的很乱,如果题目拉入杭电OJ的话,我会再改一改):
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#define N 26
using namespace std;
struct node
{
    char c;
    int num;
    struct node *next[N];
};
int temp;
struct node *root;
char str1[60], str2[60];
struct node *createNode()
{
    struct node *p = (struct node *)malloc(sizeof(struct node));
    p -> num = 1;
    for(int i = 0; i < N; i++)
        p -> next[i] = NULL;
    return p;
}
void delNum(struct node *r, int n)
{
    int cur = str2[n] - a;
    if(r -> next[cur] == NULL || r -> next[cur] -> num == 0 || n >= strlen(str2) - 1)
    {
        return ;
    }
    if(r -> next[cur] -> num >= temp)
        r -> next[cur] -> num -= temp;
    else
        r -> next[cur] -> num = 0;
    delNum(r -> next[cur], n + 1);
}
struct node *insertNode(struct node *r, int n)
{
    int cur = str2[n] - a;
    if(n >= strlen(str2))
    {
        return r;
    }
    struct node *p = r -> next[cur];
    if(r -> next[cur] == NULL)
    {
        r -> next[cur] = createNode();
    }
    else
    {
        (r -> next[cur] -> num)++;
    }
    //printf("%d", r -> next[cur] -> num);
    insertNode(r -> next[cur], n + 1);
    return r;
}
struct node *delNode(struct node *r, int n)
{
    int cur = str2[n] - a;
    struct node *p = r -> next[cur];
    if(n >= strlen(str2) - 1)
    {
        //if(r -> next[cur] != NULL)
        //printf("%d", r -> next[cur] -> num);
        if(r -> next[cur] != NULL)
        {
            temp = r -> next[cur] -> num;
            r -> next[cur] -> num = 0;
            r -> next[cur] = NULL;
            delNum(root, 0);
        }
        return r;
    }
    if(r -> next[cur] == NULL || r -> next[cur] -> num == 0)
        return r;
    //printf("%d", r -> next[cur] -> num);
    delNode(r -> next[cur], n + 1);
    return r;
}
int searchNode(struct node *r, int n)
{
    int cur = str2[n] - a;
    struct node *p = r -> next[cur];
    if(r -> next[cur] == NULL || r -> next[cur] -> num == 0)
        return 0;
    if(n >= strlen(str2) - 1)
    {
        //printf("%d", r -> next[cur] -> num);
        if(r -> next[cur] == NULL || r -> next[cur] -> num == 0)
            return 0;
        if(r -> next[cur] -> num >= 1)
            return 1;
        else
            return 0;
    }
    //printf("%d", r -> next[cur] -> num);
    return searchNode(r -> next[cur], n + 1);
}
int main()
{
    int n;
    root = createNode();
    scanf("%d", &n);
    for(int i = 0; i < n; i++)
    {
        scanf("%s%s", str1, str2);
        if(str1[0] == d)
        {
            delNode(root, 0);
        }
        else if(str1[0] == i)
        {
            insertNode(root, 0);
        }
        else
        {
            if(searchNode(root, 0) == 1)
                printf("Yes\n");
            else
                printf("No\n");
        }
    }
    return 0;
}

 

2016"百度之星" - 资格赛(Astar Round1) Problem C (Trie树)

标签:

原文地址:http://www.cnblogs.com/burning-flame/p/5496874.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!