您的位置:首页 > 其它

字典树模板

2017-07-18 14:58 246 查看
通过学习别的高手代码,我总结出一个比较实用的字典树增删查的模板

用2000000*26左右的数组存储单词字母顺序。中间记录的都是位置关系。

#include<cstdio>
#include<string>
#include<map>
#include<cstring>
#include<algorithm>
#define maxn 50
using namespace std;

typedef long long LL;
const int maxp=2064888;
char s[maxn], x[maxn];
int n, tot, cnt[maxp];
int f[maxp][26];

int main()
{
tot = 1;
cnt[1] = 0;
memset(f[0], 0, sizeof(f[0]));
while (~scanf("%s%s", s, x))
{
if (s[0] == 'i')//增添一个单词
{
int rt = 1;
for (int i = 0,j; x[i]; i++)
{
j = x[i] - 'a';
if (!f[rt][j])
{
f[rt][j] = ++tot;//发现是新单词,则改变该位置的指向,tot就是记录
cnt[tot] = 0;//记录那一行没有使用
memset(f[tot], 0, sizeof(f[tot]));//为指向的一行清理空间
}
rt = f[rt][j];//如果在这个位置已经有字母了,就移动到他指向的位置
++cnt[rt];//标记此行用过
}
}

if (s[0] == 's')//查找前缀,是否存在
{
int rt = 1;
for (int i = 0, j; x[i]; i++)
{
j = x[i] - 'a';
if (!(rt = f[rt][j]))
{
printf("No\n");
rt = 0;
break;
}
}
if (rt) printf("Yes\n");
}
/*
for(int j=1; j<22; j++)
{
printf("\n");
for(int i=0; i<26; i++)
{
if(f[j][i]==0)
printf(".");
else
printf("%d ",f[j][i]);
}

}
*/

if (s[0] == 'd')//删除拥有该前缀的所有单词
{
int rt = 1;
for (int i = 0, j; x[i]; i++)
{
j = x[i] - 'a';
if (!f[rt][j])
{
rt = 0;
break;
}
else rt = f[rt][j];
}
if (!rt) continue;
int tr = 1;
for (int i = 0, j; x[i]; i++)
{
j = x[i] - 'a';
if (!f[j]) break;
else
{
int k = f[j];
cnt[k] -= cnt[rt];
if (!cnt[k]) k = f[j] = 0;
tr = k;
}
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: