使用Trie的insert函数,主要是要灵活修改search函数,使得其可以快速搜索hat word。
思路:
1 先搜索一个word的前缀有没有在Trie树中找到,如果找到,保存这个Node,方便下面继续搜索, 就搜索余下的能不能是Trie树上的一个单词,如果找到,那么就是hat word了。
2 如果没找到,那么就沿着刚刚搜索到的前缀单词的节点继续往下搜,这样就可以加速程序,不用每次重复搜索。
3 如果沿着Trie树已经走到word的叶子节点了,那么就结束这个word的搜索了。
实现好这些思路,那么速度是很快的。
#include <stdio.h>
#include <string.h>
const int MAX_N = 50001;
const int ARR_SZIE = 26;
char dict[MAX_N][100]; //char dict[MAX_N][15]也AC,10就RE
int N;
struct Node
{
int n;
Node *arr[ARR_SZIE];
Node():n(0)
{
for (int i = 0; i < ARR_SZIE; i++)
{
arr[i] = NULL;
}
}
};
void delTrie(Node *trie)
{
if (trie)
{
for (int i = 0; i < ARR_SZIE; i++)
{
if (trie->arr[i]) delete trie->arr[i];
}
delete trie;
}
}
Node *Trie;
void insert(char *ch)
{
Node *pCrawl = Trie;
int len = strlen(ch);
for (int i = 0; i < len; i++)
{
int index = ch[i]-'a';
if (!pCrawl->arr[index]) pCrawl->arr[index] = new Node;
pCrawl = pCrawl->arr[index];
}
pCrawl->n++;
}
int pathLen;
Node *searchHat(Node *rt, char *chs, int len)
{
Node *pCrawl = rt;
for (int i = 0; i < len; i++)
{
int index = chs[i] - 'a';
if (!pCrawl->arr[index]) return NULL;
pCrawl = pCrawl->arr[index];
pathLen++;
if (pCrawl->n) return pCrawl;
}
if (pCrawl->n) return pCrawl;
return NULL;
}
bool search(Node *rt, char *chs, int len)
{
Node *pCrawl = rt;
for (int i = 0; i < len; i++)
{
int index = chs[i] - 'a';
if (!pCrawl->arr[index]) return false;
pCrawl = pCrawl->arr[index];
}
return pCrawl->n > 0;
}
int main()
{
Trie = new Node;
N = 0;
while (gets(dict[N])) insert(dict[N++]);
for (int i = 0; i < N; i++)
{
int len = strlen(dict[i]);
pathLen = 0;
Node *node = Trie;
while (pathLen < len)
{
node = searchHat(node, dict[i]+pathLen, len-pathLen);
if (pathLen < len && node)
{
if (search(Trie, dict[i]+pathLen, len-pathLen))
{
puts(dict[i]);
break;
}
}
}
}
delTrie(Trie);
return 0;
}
HDU 1247 Hat’s Words Trie题解,布布扣,bubuko.com
原文地址:http://blog.csdn.net/kenden23/article/details/38361791