【笔记】Trie 树
边代表字符,0 节点为根。
模板:字符串匹配
在词典中查询是否存在某个单词
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 100005;
struct Trie {
int nxt[MAXN][26], cnt;
bool flg[MAXN];
Trie() {
cnt = 0;
memset(nxt, 0, sizeof(nxt));
memset(flg, 0, sizeof(flg));
}
// 插入
void insert(char s[]) {
int len = strlen(s), p = 0;
for (int i=0; i< len; i++) {
int c = s[i] - 'a';
if (!nxt[p][c]) nxt[p][c] = ++cnt;
p = nxt[p][c];
}
flg[p] = 1; // 表示该节点作为字符串末尾
}
// 匹配
int find(char s[]) {
int len = strlen(s), p = 0;
for (int i=0; i< len; i++) {
int c = s[i] - 'a';
if (!nxt[p][c]) return 0;
p = nxt[p][c];
}
return flg[p];
}
} trie;
int main()
{
int N, M; char s[MAXN];
scanf("%d%d", &N, &M);
for (; N; N--) { scanf("%s", s); trie.insert(s); }
for (; M; M--) { scanf("%s", s); printf("%d\n", trie.find(s)); }
}
拓展
[TJOI2010]阅读理解
把字符串的集合称为“文章”。flg 类型换成 vector ,一棵 Trie 树就可以同时记录多个文章了(降空间)。
void insert(char s[], int k) {
...
if (不含 k) flg[p].push_back(k);
}
01-Trie
CF665E
luoguP4551 最长异或路径
处理有关二进制数值大小的东西,反正是有高低位之分的东西
void insert(int s) {
int p = 0;
for (int o=1<<30; o; o>>=1) {
int c = (s&o) > 0;
if (!nxt[p][c]) nxt[p][c] = ++tot;
p = nxt[p][c];
}
}

浙公网安备 33010602011771号