码迷,mamicode.com
首页 > 其他好文 > 详细

(hdu step 5.2.2)统计难题(求一堆单词中以某一单词为前缀的单词的个数)

时间:2015-03-08 13:04:36      阅读:111      评论:0      收藏:0      [点我收藏+]

标签:

题目:

统计难题

Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131070/65535 K (Java/Others)
Total Submission(s): 349 Accepted Submission(s): 209
 
Problem Description
Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀).
 
Input
输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串.

注意:本题只有一组测试数据,处理到文件结束.
 
Output

            对于每个提问,给出以该字符串为前缀的单词的数量.
 
Sample Input
banana
band
bee
absolute
acm

ba
b
band
abc
 
Sample Output
2
3
1
0
 
Author
Ignatius.L
 
 
Recommend
Ignatius.L


题目分析:

               Trie的基本题。这道题提交的时候使用C++提交,使用G++提交会MLE。而且杭电有时候很搞笑的,这道题

很快就敲出来了,提交以后一直TLE。后来中午再交一次的时候,就正常了,在200ms左右。如果TLE了就多交几次吧。。



代码如下:

/*
 * b.cpp
 *
 *  Created on: 2015年3月8日
 *      Author: Administrator
 */

#include <iostream>
#include <cstdio>
#include <cstring>


using namespace std;

const int MAX = 26;

typedef struct TrieNode{//Trie结点
	int prefix;//到当前节点的前缀数
	struct TrieNode* next[MAX];//当前节点的孩子节点
}Trie;


/**
 * Trie树的插入操作:
 * 将字符串s插入到以root为根的字典树中
 *
 */
void insert(Trie* root,char* s){
	//如果当前的字典树的根为空||要插入的字符串为空
	if(root == NULL || *s == ‘\0‘){
		return ;//则直接返回
	}

	Trie* p = root;

	while(*s != ‘\0‘){//不断地遍历要插入的字符串的每一个字符
		if(p->next[*s - ‘a‘] == NULL){//如果字典树中还没有该节点,则新建该节点
			//新建结点的初始化操作
			Trie* temp = (Trie*)malloc(sizeof(Trie));
			int i;
			for(i = 0 ; i < MAX ; ++i){
				temp->next[i] = NULL;
			}
			temp->prefix = 1;//新建该节点后的前缀数默认为1

			p->next[*s-‘a‘] = temp;//用next指向temp
			p = p->next[*s-‘a‘];//遍历下一个节点
		}else{//如果该节点在字典树中已经存在
			p = p->next[*s - ‘a‘];//遍历下一个节点
			p->prefix++;//到该节点的前缀数+1
		}

		s++;//遍历该字符串的下一个字符
	}
}


/**
 * 在以root为根字典树中寻找以pre为前缀的单词数有多少个
 */
int count(Trie* root,char* pre){
	Trie* p = root;

	while(*pre != ‘\0‘){//不断地遍历该前缀字符串
		if(p->next[*pre - ‘a‘] == NULL){//如果某一结点的孩子节点中不包含pre当前遍历的字符
			return 0;//则表明单词中没有一pre为前缀的单词,直接返回0
		}else{//如果当前节点的孩子节点中有pre当前遍历到的字符
			//则继续遍历
			p = p->next[*pre - ‘a‘];
			pre++;
		}
	}

	return p->prefix;//返回以pre开头的单词数
}


/**
 * 字典树的释放操作
 */
void del(Trie* root){
	int i;
	for(i = 0 ; i < MAX ; ++i){
		if(root->next[i] != NULL){
			del(root->next[i]);
		}
	}

	free(root);
}


int main(){

	char str[11];

	//初始化操作
	Trie* root = (Trie*)malloc(sizeof(Trie));
	int i;
	for(i = 0 ; i < MAX ;++i){
		root->next[i] = NULL;
	}
	root->prefix = 0;


	while(gets(str)){//不断地读入字符串
		if(strcmp(str,"") == 0){//如果当前读入的是空串
			break;//则跳出循环
		}

		insert(root,str);//将当前读到的字符串插入字典树中
	}

	while(gets(str)){
		printf("%d\n",count(root,str));
	}

	del(root);//如果没有这个操作耗时只有100ms左右。如果加上这个操作耗时将达到200ms左右。

	return 0;
}












(hdu step 5.2.2)统计难题(求一堆单词中以某一单词为前缀的单词的个数)

标签:

原文地址:http://blog.csdn.net/hjd_love_zzt/article/details/44131937

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!