字典树笔记

1.作用

做题啊
通过字典树可以快速、简单地查找字符串
并且存储的空间也可以节省

2.实现

例如:
现有ab,ac,d 3个字符串

那么塞进Trie树里面就是这样的:
在这里插入图片描述

  • get

顺着以前已经确立的字母往下走,
在字符串的终点打上标记即可

图中的字母可以理解为树的边权
经过的路线所对印的字符串就是把这些权值按顺序拼凑起来了

字典树的操作有简单的两种为 插入 & 查询

设数组 T r e e Tree 存储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);
}

  1. Tree[i,j]=k,i表示当前节点的编号,j表示边权,k表示目标节点的编号 ↩︎

发布了23 篇原创文章 · 获赞 37 · 访问量 9062

猜你喜欢

转载自blog.csdn.net/weixin_41221124/article/details/103897395