字典树称单词查找树, Trie树,是一种 树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。
它有3个基本性质:
1 根节点不包含字符,除根节点外每一个节点都只包含一个字符。
2 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
3 每个节点的所有子节点包含的字符都不相同。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
const int M = 1e4 + 5;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
typedef long long ll;
int tree[N][26]; /// 26代表26个字母,根据题目需要也可以换成别的字符数量
int num[N]; /// 到该结点形成的字符串的前缀数量(包括本身)
int pos; /// 初始值为1
void Insert(char* word)
{
int u = 0;
int len = strlen(word);
for (int i = 0; i < len; i++){
int v = word[i] - '0';
if (tree[u][v] == 0){
tree[u][v] = pos++;
}
u = tree[u][v];
num[u]++;
}
}
int Find(char* word) //返回以某个字符串为前缀的单词的数量
{
int u = 0;
int len = strlen(word);
for (int i = 0; i < len; i++){
int v = word[i] - '0';
if (tree[u][v] == 0) return 0;
u = tree[u][v];
}
return num[u];
}
HDU 1671 题目链接
题意
给出n个字符串,如果一个字符串是另一个字符串的前缀就输出NO,否则输出YES
思路
字典树模板题(N的数量不能太大,会超内存)
#include <bits/stdc++.h>
using namespace std;
const int N = 3e5 + 5;
const int M = 1e4 + 5;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
typedef long long ll;
int tree[N][10];
int num[N];
char word[M][13];
int pos; /// 初始值为1
void Insert(char* word)
{
int u = 0;
int len = strlen(word);
for (int i = 0; i < len; i++){
int v = word[i] - '0';
if (tree[u][v] == 0){
tree[u][v] = pos++;
}
u = tree[u][v];
num[u]++;
}
}
int Find(char* word) //返回以某个字符串为前缀的单词的数量
{
int u = 0;
int len = strlen(word);
for (int i = 0; i < len; i++){
int v = word[i] - '0';
if (tree[u][v] == 0) return 0;
u = tree[u][v];
}
return num[u];
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
int n;
scanf("%d",&n);
memset(tree,0,sizeof(tree));
memset(num,0,sizeof(num));
pos = 1;
for (int i = 0; i < n; i++){
scanf("%s",word[i]);
Insert(word[i]);
}
bool flag = true;
for (int i = 0; i < n; i++){
if (Find(word[i]) > 1){
flag = false;
break;
}
}
if (flag) cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}