首页 > 代码库 > HDU 1247 Hat’s Words Trie题解

HDU 1247 Hat’s Words Trie题解

使用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;
}