Trie树
描述
以空间换时间的一种字符串统计和查找算法。方法是将单词按照字母顺序逐一插入trie树,插入更多单词时从头开始找,如果有重复就重复的字母以下插入,以此得到一棵trie树。Trie树的每个节点上都可以维护一些值,例如存放到这里的单词的出现次数等。
代码模板
#include <bits/stdc++.h>
struct trie_t
{
int count;
trie_t *child[26];
};
trie_t* create()
{
trie_t *node = new trie_t;
node->count = 0;
for (int i = 0; i < 26; i++)
node->child[i] = nullptr;
return node;
}
void insert(trie_t* root, char *key)
{
trie_t* node = root;
char *p = key;
while (*p)
{
if (node->child[*p - 'a'] == nullptr)
{
node->child[*p - 'a'] = create();
}
node = node->child[*p - 'a'];
p++;
}
node->count += 1;
}
int search(trie_t* root, char* key)
{
trie_t* node = root;
char *p = key;
while (*p && node != nullptr)
{
node = node->child[*p - 'a'];
++p;
}
if (node == nullptr)
return 0;
return node->count;
}
例题
UVA 11362
#include <bits/stdc++.h>
struct trie_t
{
int count;
bool owari;
trie_t *child[10];
};
trie_t* create()
{
trie_t *node = new trie_t;
node->count = 0;
node->owari = false;
for (int i = 0; i < 10; i++)
node->child[i] = nullptr;
return node;
}
bool insert(trie_t* root, char *key)
{
trie_t* node = root;
char *p = key;
while (*p)
{
if (node->owari)
return false;
if (node->child[*p - '0'] == nullptr)
{
node->child[*p - '0'] = create();
}
node = node->child[*p - '0'];
p++;
}
node->count += 1;
node->owari = true;
return node->owari;
}
char s[19932][20] = { 0 };
int main(int argc, char **argv)
{
int T;
std::cin >> T;
while (T--)
{
std::memset(s, 0, sizeof s);
trie_t* root = create();
int n;
std::cin >> n;
bool flag = false;
for (int i = 1; i <= n; i++)
{
std::cin >> s[i];
if (!insert(root, s[i]))
{
flag = true;
std::cout << "NO\n";
break;
}
}
if (!flag)
std::cout << "YES\n";
}
}