【笔记】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];
	}
}
posted @ 2021-02-18 22:36  zrkc  阅读(47)  评论(0)    收藏  举报