您的位置:首页 > 其它

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

2016-05-17 17:21 387 查看
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: