trie字典树
字典树,顾名思义,是一个树形结构。有唯一的根节点。每次插入一个字符串的时候,首先扫描字符串,然后从第一个字符开始逐个插入。
例如: 插入字符串 "abcd"
1、一定是从根节点开始,用一个节点p指向根节点。
2、首先判断p是否有一个子节点指向字符当前字符(第一个就是'a'),如果没有就新建一个子节点,并且将trie[p][a]指向新建节点,将当前的指针指向新建节点,否则就直接指向该节点。
3、继续遍历下一个字符,重复步骤 2。
4、在插入最后一个字符的时候,将节点p正在中进行标记,表示该节点是一个字符串结束的位置,目的是为了检索的方便。
检索字符串的时候也按照插入的方式一个个字符向下走就可以了。用一个数组来标记插入的每一个字符串的结束位置,如果检索字符串检索到了(即路径上没有空节点),且最后一个字符所在的节点在
中被标记了,那么说明该字符串存在过。
#include <bits/stdc++.h>
#pragma warning (disable:4996)
#pragma warning (disable:6031)
#define mem(a, b) memset(a, b, sizeof a)
using namespace std;
const int N = 310;
int trie[N][26];
int cnt;
int root;
bool nd[N];
void insert(char* s) {
int len = strlen(s);
int p = root;
for (int i = 0; i < len; i++) {
if (trie[p][s[i] - 'a'] == 0) {
++cnt;
trie[p][s[i] - 'a'] = cnt;
}
p = trie[p][s[i] - 'a'];
}
nd[p] = 1;
}
bool check(char* s) {
int len = strlen(s);
int p = root;
for (int i = 0; i < len; i++) {
if (trie[p][s[i] - 'a'] == 0)return false;
p = trie[p][s[i] - 'a'];
}
return nd[p];
}
int main()
{
root = 0;
cnt = 0;
mem(nd, 0);
mem(trie, 0);
char s[10];
for (int i = 0; i < 5; i++) {
scanf("%s", s);
insert(s);
}
for (int i = 0; i < 10; i++) {
scanf("%s", s);
if (check(s)) {
printf("Yes : %s\n", s);
}
else printf("NO : Sorry\n");
}
return 0;
}
本文来自博客园,作者:correct,转载请注明原文链接:https://www.cnblogs.com/correct/p/12861930.html

浙公网安备 33010602011771号