1.作用
做题啊
通过字典树可以快速、简单地查找字符串
并且存储的空间也可以节省
2.实现
例如:
现有ab,ac,d 3个字符串
那么塞进Trie树里面就是这样的:
- get
顺着以前已经确立的字母往下走,
在字符串的终点打上标记即可
图中的字母可以理解为树的边权
经过的路线所对印的字符串就是把这些权值按顺序拼凑起来了
字典树的操作有简单的两种为 插入 & 查询
设数组 存储Trie树1
2.1 插入操作
简单总结一下的话呢,
就是该字符如果没有在对应的根下面出现过那么就插入,否则就顺着树往下走
int insert() {
int len = strlen(str), root = 0;
for (int i = 0 ; i < len ; i++) {
char id = str[i];
if (tree[root][id] == 0) {
tot++;
tree[root][id] = tot;
}
root = tree[root][id];
}
flag[root] = 1;
return 0;
}
2.2 查询操作
标记已经打好了
判断有没有打标记总会吧
不会我也没办法
扫描二维码关注公众号,回复:
8609258 查看本文章
3.例题
题目描述
新学期开学有几天了,Capo发现班上有一个老师,这位老师喜欢每天上课前先点名,并且是随机抽点。今天,Capo突然发现自己被点到了两次,于是Capo开始质疑老师的点名是否有重复或误报为其他班的同学。当然Capo可不想一个个比较,所以他把这个任务交给了你,当然Capo会提供班上人数n和他们的名字,同时Capo也会记下老师报的名字。
样例输入
5
a
b
c
ad
acd
3
a
a
e
样例输出
OK
REPEAT
WRONG
AC代码:
#include <bits/stdc++.h>
using namespace std;
int tree[500005]['z'], flag[500005], tot;
char str[55];
int insert() {
int len = strlen(str), root = 0;
for (int i = 0 ; i < len ; i++) {
char id = str[i];
if (tree[root][id] == 0) {
tot++;
tree[root][id] = tot;
}
root = tree[root][id];
}
flag[root] = 1;
return 0;
}
int search() {
int len = strlen(str), root = 0;
for (int i = 0 ; i < len ; i++) {
char id = str[i];
if (tree[root][id] == 0) {
return 0;
}
root = tree[root][id];
}
if (flag[root] == 0) {
return 0;
}
flag[root]++;
return flag[root];
}
int main() {
freopen("name.in","r",stdin);
freopen("name.out","w",stdout);
int n, m;
scanf("%d",&n);
for (int i = 1 ; i <= n ; i++) {
scanf("%s",&str);
insert();
}
scanf("%d",&m);
for (int i = 1; i <= m ; i++) {
scanf("%s",str);
int temp = search();
if (temp == 0) {
printf("WRONG\n");
}
if (temp == 2) {
printf("OK\n");
}
if (temp > 2) {
printf("REPEAT\n");
}
}
return 0;
fclose(stdin);
fclose(stdout);
}
Tree[i,j]=k,i表示当前节点的编号,j表示边权,k表示目标节点的编号 ↩︎