1、insert : 往神奇字典中插入一个单词
2、delete: 在神奇字典中删除所有前缀等于给定字符串的单词
3、search: 查询是否在神奇字典中有一个字符串的前缀等于给定的字符串
code:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<iostream>
#include<string>
#include<map>
#include<algorithm>
using namespace std;
typedef long long ll;
#define mod 9973
#define MAX 26
const int N = 1e5+10;
typedef struct TrieNode
{
int freq; //该结点前缀出现的次数
TrieNode *next[MAX]; //数组大小以字符种类数量为准
}TrieNode;
TrieNode *Root;
//初始化一个节点。freq计数为1,next都为NULL
TrieNode* CreateTrieNode()
{
TrieNode *p;
p = (TrieNode*)malloc(sizeof(TrieNode));
p->freq = 1;
for(int i=0; i<MAX; i++)
p->next[i] = NULL;
return p;
}
void InsertTrie(char *s)
{
TrieNode *p = Root;
for(int i=0; s[i]; i++)
{
int id = s[i]-'a'; //hash
if(p->next[id] == NULL)
{
TrieNode* tmp = CreateTrieNode();
p->next[id] = tmp;
p = p->next[id];
}
else
{
p = p->next[id];
p->freq++;
}
}
}
int SearchTrie(char *s) //返回在字典中以此字符串为前缀的数量
{
TrieNode *p = Root;
for(int i=0; s[i]; i++)
{
int id = s[i]-'a';
if(p->next[id] == NULL) return 0;
p = p->next[id];
if(p->freq <= 0) return 0;
}
return p->freq;
}
void DeleteTrie(char *s) //从字典中删除以此字符串为前缀的单词
{
TrieNode *p = Root;
int len = strlen(s), num = SearchTrie(s);
for(int i=0; i<len; i++)
{
int id = s[i]-'a';
if(i == len-1)
{
p->next[id] = NULL;
//将连接到最后字符结点的路径去掉
}
if(p->next[id] == NULL)
{
break;
}
else
{
p = p->next[id];
p->freq -= num; //每个结点的前缀计数都要减去受影响的个数
}
}
}
int main()
{
int n;
char s[35], ss[35]; //第一个字符串为操作类型,第二个字符串为操作内容
Root = CreateTrieNode(); //Initial
scanf("%d", &n); //操作次数
while(n--)
{
scanf("%s%s", s,ss);
if(s[0] == 'i') InsertTrie(ss);
else if(s[0] == 'd') DeleteTrie(ss);
else
{
if(SearchTrie(ss) > 0) puts("Yes");
else puts("No");
//printf("%d\n", SearchTrie(ss));
}
}
return 0;
}