字典树

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

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;

}

你可能感兴趣的:(字典树)