「学习笔记」字典树(Trie)
最近补知识点补疯了!
字典树,顾名思义,就是一棵像字典的树
这棵字典树从根节点到某一结点,这一路径就构成了一个字符串,放张图
该图片来自
这个字典树用边来代表字母, 代表着字符串 ,一般的只包含小写字母的字典树,是一个 叉树,但是字典树并不是都是 叉的,根据题目需要,有 叉的,有 叉的,等等。
字典树有插入 insert
和查找 find
两个操作,其实只要理解了上面的图,这些就都会了,每个节点都可以储存信息,根据题目要求来。
封装的 Trie
struct Trie {
int cnt;
int ch[N][62], cot[N];
inline void init() {
memset(ch[0], 0, sizeof ch[0]);
cot[0] = 0;
cnt = 0;
}
inline int getnum(const char x) {
if (x >= 'A' && x <= 'Z') {
return x - 'A';
}
if (x >= 'a' && x <= 'z') {
return x - 'a' + 26;
}
if (x >= '0' && x <= '9') {
return x - '0' + 52;
}
return 0;
}
inline void insert(const char s[]) {
int cur = 0, l = strlen(s);
for (int i = 0; i < l; ++ i) {
int c = getnum(s[i]);
if (!ch[cur][c]) {
ch[cur][c] = ++ cnt;
cot[cnt] = 0;
memset(ch[cnt], 0, sizeof ch[cnt]);
}
cur = ch[cur][c];
cot[cur] ++;
}
}
inline int find(const char s[]) {
int cur = 0, l = strlen(s);
for (int i = 0; i < l; ++ i) {
int c = getnum(s[i]);
if (!ch[cur][c]) return 0;
cur = ch[cur][c];
}
return cot[cur];
}
} trie;
洛谷模板题的完整代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll read() {
ll x = 0;
int fg = 0;
char ch = getchar();
while (ch < '0' || ch > '9') {
fg |= (ch == '-');
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = (x << 3) + (x << 1) + (ch ^ 48);
ch = getchar();
}
return fg ? ~x + 1 : x;
}
const int N = 3e6 + 5;
int T, cnt, n, q;
int ch[N][62], cot[N];
char s[N];
void init() {
for (int i = 0; i <= cnt; ++ i) {
cot[i] = 0;
for (int j = 0; j <= 61; ++ j) {
ch[i][j] = 0;
}
}
cnt = 0;
}
int getnum(char x) {
if (x >= 'A' && x <= 'Z') {
return x - 'A';
}
if (x >= 'a' && x <= 'z') {
return x - 'a' + 26;
}
if (x >= '0' && x <= '9') {
return x - '0' + 52;
}
return 0;
}
void insert(char s[]) {
int cur = 0, l = strlen(s);
for (int i = 0; i < l; ++ i) {
int c = getnum(s[i]);
if (!ch[cur][c]) {
ch[cur][c] = ++ cnt;
}
cur = ch[cur][c];
cot[cur] ++;
}
}
int find(char s[]) {
int cur = 0, l = strlen(s);
for (int i = 0; i < l; ++ i) {
int c = getnum(s[i]);
if (!ch[cur][c]) return 0;
cur = ch[cur][c];
}
return cot[cur];
}
void work() {
n = read(), q = read();
for (int i = 1; i <= n; ++ i) {
scanf("%s", s);
insert(s);
}
for (int i = 1; i <= q; ++ i) {
scanf("%s", s);
printf("%d\n", find(s));
}
}
int main() {
T = read();
while (T --) {
init();
work();
}
return 0;
}
作者:yifan0305
出处:https://www.cnblogs.com/yifan0305/p/17035123.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
转载时还请标明出处哟!
朝气蓬勃 后生可畏
Buy me a cup of coffee ☕.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探