HDU 2846 字典树

算法步骤:

1.读取n,n表示商品数量,即单词的个数
2.对每个单词进行循环插入操作,比如ade,就把ade,ad,e都插入字典树中
3.插入函数insert():两个参数,第一个是单词首地址,第二个是当前插入单词的id(  
第几个插入进树的单词),然后逐字符的对单词扫描,以ade为例,首先指针next指向
Root,如果Root->child[*word-'a']这个子孩子不存在,就New一个新节点。然后当next
指针指向这个子孩子,如果当前传进来的Id和上次保存的Id不一样,则Count++并且把Id
改为当前Id

4.查询函数query(): 很简单,一目了然。返回值是最后节点中count的值,就是答案。

问题:因为每个单词都要反复调用insert()函数,开销比较大,如果一个单词长度是20,那么就要调用20次,可以把insert()写得再丰满一点,可以一次性的处理完这些操作


// 已AC  耗时250 ms 最短的是78ms 有待优化
#include <stdio.h>
#include <string.h>
//#include <time.h>

struct node{
	int count;
	node * child[26];
	int id;
	node(){
		count = 0;
		id = -1;
		memset(child, 0, sizeof(child));
	}
} * root = new node();

void insert(char * word, int id)
{
	node * next = root;	
	while(*word)
	{
		if(next->child[*word-'a'] == NULL)
		{
			next->child[*word-'a'] = new node();			
		}		
		next = next->child[*word-'a'];
		
		if(id != next->id)
		{
			next->count++;
			next->id = id;
		}
		word++;
	}
}

int query(char * key)
{
	node * next = root;
	while(*key)
	{
		if(next->child[*key-'a'] == NULL)
			return 0;
		else
			next = next->child[*key-'a'];
		
		key++;
	}
	return next->count;
}

int main(void)
{
	//freopen("E:\\input.txt", "r", stdin);
	int n;
	char word[23];
	char * ptr_word;
	scanf("%d", &n);	
	for(int i=0; i<n; i++)
	{
		scanf("%s", word);
		ptr_word = word;

		while(*ptr_word)
		{
			insert(ptr_word, i);
			ptr_word++;
		}	
	}
	scanf("%d", &n);
	while(n--)
	{
		scanf("%s", word);
		printf("%d\n", query(word));
	}
	//printf("Time used: %d ms\n",  clock());
	return 0;
}


你可能感兴趣的:(算法,优化,null,query,insert)