Hdu-1251 统计难题

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1251

解题思路:

字典树的典型应用——插入,查询。

1.插入时候,不是字母结束时将head->count++,而是遇到字母:

没出现过:初始化1,表明此次出现

出现过:count++

这样,head->count记录的就是从根结点到head结点的前缀出现的次数。

2.查询

返回单词结尾字母的count就是前缀出现的次数。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

struct Dictree //结点内容
{
	int count;
	Dictree *tire[26];
}*a; //a为根结点,不存信息,是字典树的入口

void init() //初始化,不能忘。。。。
{
	a = new Dictree;
	for(int i = 0; i < 26; ++i)
		a->tire[i] = NULL;
}

void insert(char str[]) //插入
{
	int len, cur;
	Dictree *head = a; //每次从根结点(a)开始查询
	len = strlen(str);
	for(int i = 0; i < len; ++i)
	{
		cur = (int)(str[i] - 97); //对应字母和下标匹配
		if(head->tire[cur] == NULL) //字母不存在
		{
			head->tire[cur] = new Dictree;
			head = head->tire[cur]; //和下一句顺序不能反
			head->count = 1;
			for(int j = 0; j < 26; ++j)
				head->tire[j] = NULL;
		}
		else //存在
		{
			head = head->tire[cur];
			head->count++;
		}
	}
}

int search(char str[]) //查询
{
	int len, cur;
	Dictree *head = a;
	len = strlen(str);
	for(int i = 0; i < len; ++i)
	{
		cur = (int)(str[i] - 97);
		if(head->tire[cur] == NULL) //无查询结果
			return 0;
		else
			head = head->tire[cur];
	}
	return head->count; //前缀出现次数
}

int main()
{
	char str[11], que[11];
	int temp, query, count;
	init();
	while(gets(str) && strcmp(str, "") != 0) //输入方法不会~~~查了下
		insert(str);
	while(scanf("%s", que) != EOF)
	{
		count = search(que);
		printf("%d\n", count);
	}
	return 0;
}


你可能感兴趣的:(null,search,query,insert)