1.题面
http://acm.hdu.edu.cn/showproblem.php?pid=5687
2.题意
实现一个数据结构,支持一下三种操作
1、insert : 往神奇字典中插入一个单词
2、delete: 在神奇字典中删除所有前缀等于给定字符串的单词
3、search: 查询是否在神奇字典中有一个字符串的前缀等于给定的字符串
3.思路
WA了一晚上,倒不是tire树的实现有多么复杂,貌似是我把题目给理解错了。
过了之后看了一下别人的题解貌似都是一个节点里开26个指针过的,窃以为这种方法在节点多的时候容易爆内存。
我是用链树写的,没有使用动态内存分配,而是一开始申请了一块很大的空间。
其实我一直都很好奇,链树写的tire树省内存但是容易超时到底是因为指针之间移动耗时大,还是new操作耗时大。
没有使用动态内存分配的tire树是不是会快上很多呢?
这个问题以后讨论。
我记得我是有一个原创的折中方法的。
4.代码
/*****************************************************************
> File Name: Cpp_Acm.cpp
> Author: Uncle_Sugar
> Mail: uncle_sugar@qq.com
> Created Time: 2016年05月16日 星期一 19时39分43秒
*****************************************************************/
# include <cstdio>
# include <cstring>
# include <cctype>
# include <cmath>
# include <cstdlib>
# include <climits>
# include <iostream>
# include <iomanip>
# include <set>
# include <map>
# include <vector>
# include <stack>
# include <queue>
# include <algorithm>
using namespace std;
const int debug = 1;
const int size = 3000000 + 10;
const int INF = INT_MAX>>1;
typedef long long ll;
struct node{
char data;
int pass;
int right,child;
}tire[size];
int head,len;
void Insert(int& addr,char *s){
if (addr==0){
addr = len++;
tire[addr].data = *s;
tire[addr].pass = 0;
tire[addr].right = tire[addr].child = 0;
}
if (tire[addr].data == *s){
tire[addr].pass++;
if (*s!='\0')
Insert(tire[addr].child,s+1);
}else {
Insert(tire[addr].right,s);
}
}
void Search(int& addr,char *s){
if (addr == 0){
cout << "No" << endl;
return;
}
if (*s=='\0'){
cout << "Yes" << endl;
return;
}
if (tire[addr].data == *s){
Search(tire[addr].child,s+1);
}else {
Search(tire[addr].right,s);
}
}
int Delete(int& addr,char *s){
if (addr==0)
return 0;
int ret = 0;
if (tire[addr].data == *s){
if (*(s+1)=='\0') ret = tire[addr].pass;
else {
ret = Delete(tire[addr].child,s+1);
}
tire[addr].pass -= ret;
if (tire[addr].pass==0)
addr = tire[addr].right;
}else {
ret = Delete(tire[addr].right,s);
}
return ret;
}
char cmd[size];
char str[size];
int main()
{
std::ios::sync_with_stdio(false);cin.tie(0);
int i,j;
int n;
cin >> n;
head = 0;len = 1;
while (n--){
cin >> cmd >> str;
switch(cmd[0]){
case 'i':Insert(head,str);break;
case 'd':Delete(head,str);break;
case 's':Search(head,str);break;
}
}
return 0;
}