字典树,就是树形的字母排列,从根节点开始(根节点不代表任何字母),它的每一个子节点都有一个不同的字母,这样,从根节点开始沿任何路径到达一个叶子节点,路过的字母组合就是一个字符串,字典树在字符串的存储和查找上有很大的优越性,下面是用字典树写的两个题。

hdu 1251

/*
这道题就是标准的字典树,存储给出的所有的在字典中给出的字符串和其前缀,统计其数目,存储在字典树中,然后就可以在O(len(m))的时间内查询给出的模式串的答案了
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct Trie{
	int v;
    struct Trie *next[26];
} root;
void creat(char *str)
{
	int len = strlen(str);
	struct Trie *p = &root,*q;
	for (int i = 0; i< len; i++){
		int id = str[i] - 'a';
		if (p->next[id] == NULL){
			q = (Trie *)malloc(sizeof(root));
			q->v = 1;
			for (int j = 0; j< 26; j++)
				q->next[j] = NULL;
			p->next[id] = q;
			p = p->next[id];
		}
		else {
			p->next[id]->v++;
			p = p->next[id];
		}
	}
}
int search(char *str)
{
	int len = strlen(str);
	struct Trie *p;
	p = &root;
	for (int i = 0; i< len; i++){
		int id = str[i] - 'a';
		p = p->next[id];
		if (p == NULL) return 0;
	}
	return p->v;
}
int main()
{
	char str[15];
	int i;
	
	for (i = 0; i< 26; i++)
		root.next[i] = NULL;
	while (gets(str) && str[0] != '\0')
		creat(str);
	memset(str,0,sizeof(str));
	while (scanf ("%s",&str) != EOF){
		int ans = search(str);
		printf ("%d\n",ans);
	}
	return 0;
}
pku 1204
这一题我纠结了n久,本来改用AC自动机的(下一篇博客里讲),因为数据规模的原因,字典树都能暴过,而且由于我的AC自动机学的不怎么的,两个程序跑的时间差不多。。。。
/*
这一题用字典树纯属数据的原因,对所给的模式串建树,再对原图中每个节点的八个方向进行匹配,没有超时很是奇怪
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct Trie{
	int count;
	struct Trie *fail;
	struct Trie *next[26];
} *root,*queue[500005];
int n,m,result[1005][2];
char map[1005][1005],ans[1005];
int dir[8][2] = {{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};
void insert(char *s,int k)
{
    int len = strlen(s),i;
	struct Trie *p = root,*q;
	for (i = 0; i< len; i++){
		int id = s[i] - 'A';
		if (p->next[id] == NULL){
			q = (struct Trie *)malloc(sizeof(Trie));
			memset(q->next,NULL,sizeof(q->next));
			q->count = -1; p->next[id] = q; p = q;
		}
		else p = p->next[id];
	}
	p->count = k;
}
void search(int x,int y,int k)
{
	int x1 = x,y1 = y;
	struct Trie *p = root;
	while (x1 >= 0 && y1 >= 0 && x1 < n && y1 < m){
		int id = map[x1][y1] - 'A';
		if (p->next[id] == NULL) break;
		else p = p->next[id];
		if (p ->count != -1){
			result[p->count][0] = x; result[p->count][1] = y;
			ans[p->count] = k + 'A'; p->count = -1;
		}
		x1 += dir[k][0]; y1 += dir[k][1];
	}
}
void solve(int sum)
{
	int i,j,k;
	for (i = 0; i< n; i++)
		for (j = 0; j< m; j++)
			for (k = 0; k< 8; k++)
				search(i,j,k);
    for (i = 0; i < sum; i++)
		printf ("%d %d %c\n",result[i][0],result[i][1],ans[i]);

}
int main()
{
	int i,k;
	char word[2005];
	scanf ("%d%d%d",&n,&m,&k);
	memset(map,0,sizeof(map));
	root = (struct Trie *)malloc(sizeof(Trie));
	memset(root->next,NULL,sizeof(root->next));
	for (i = 0; i < n; i++)	scanf ("%s",&map[i]);
	getchar();
	for (i = 0; i< k; i++){
		gets(word);
		insert(word,i);
	}
	solve(k);
	return 0;
}
posted on 2010-07-21 10:36  looker  阅读(451)  评论(0编辑  收藏  举报