统计单词出现的次数并按单词出现的次数顺序输出单词及其次数

这是一道笔试题来的,主要是用字典树来解决:

/******************************************
 *
 * 描述:这是一道笔试题,要求按单词出现的次序打印出单词及其出现的次数;
 *
 * 思路:既然是笔试题,肯定要考虑时间复杂度,字典树要比哈斯的要好,
 * 因此我用了字典树.
 *
 * author: huangkq1989@scut2008
 * blog:http://blog.csdn.net/kangquan2008
 *
 * ****************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define SIZE 26  // 字符的种类数
#define DIFFERENCE_WORD_SIZE 10000 //不同的单词的个数
#define WORD_MAX_LENGTH 10 // 单词的最大长度
#define CHECK_RET(ret,info) \
	if((ret) < 0) printf("error:%s\n",(info)),exit(EXIT_FAILURE)

typedef struct Trie{
	int cnt;// 该字符在该位置出现的次数
	int times;// 标识为词尾
	int sequence;// 出现的次序,0为初始值,从1开始
	struct Trie * next[SIZE];
}*Trie, Node;

typedef struct Result{
	char data[WORD_MAX_LENGTH];
	int times;
}Result;

int seq = 0;  // 记录出现的次序
Result result[DIFFERENCE_WORD_SIZE];

int initial(Node ** node)
{
	//Node * node = *node_arg;
	if(((*node) = malloc(sizeof(Node))) == NULL)
		return -1;

	(*node)->cnt = 1;
	(*node)->sequence = 0;
	(*node)->times = 0;
	for(int i=0; i<SIZE; i++)
		(*node)->next[i] = NULL;

	return 0;
}


int insert(Trie * tree2,char src[])
{
	Trie tree = *tree2; // 为再次插入做准备
	if(tree == NULL)// 空树,注意字典树的根不存放字符
	{
		CHECK_RET(initial(&tree),"not more memory");
		*tree2 = tree; // 这步很重要,要注意,目的是把tree2指向正确分配了空间的地方
	}

	int i=0;
	Node * node;
	while(src[i] != '\0')
	{
		int flag = 0;
		int ch_to_index = src[i] - 'a';
		if(!(tree)->next[ch_to_index])// 未存在
		{
			CHECK_RET(initial(&node),"not more memory");
			(tree)->next[ch_to_index] = node;
			flag = 1;
		}else{// 存在
			(tree)->next[ch_to_index]->cnt += 1;
		}

		if(src[i+1] == '\0')
		{
			if(flag)
				(tree)->next[ch_to_index]->sequence = seq++;
			(tree)->next[ch_to_index]->times += 1;
			break;
		}

		(tree) = (tree)->next[ch_to_index];
		i++;
	}
}

void traverse_tree(Trie tree, char word[],int index)
{
	if(tree == NULL)
		return ;

	for(int i=0; i<SIZE; i++)
	{
		if(tree->next[i])
		{
			word[index] = i+'a';
			if(tree->next[i]->times > 0) // 表示是一个单词
			{
				word[index+1] = '\0';
				//printf("in traverse: %s ",word);
				//printf("%d\n",tree->next[i]->sequence);
				strcpy(result[tree->next[i]->sequence].data,word);
				result[tree->next[i]->sequence].times = tree->next[i]->times;
			}
			traverse_tree(tree->next[i],word,index+1);
		}
	}
}

void display()
{
	for(int i=0; i<seq; i++)
		printf("%s appears %d times\n", result[i].data, result[i].times);
}

int main()
{
	char set[][10] = {"efgd","abc","abc","abcd","dbc","fdd"};
	Trie tree = NULL;
	printf("trie tree has:\n");
	for(int i=0; i<sizeof(set)/sizeof(set[0]); i++)
		printf("%s\n",set[i]),insert(&tree,set[i]);
	printf("-------------------\n");

	printf("按单词出现的次序打印出单词及其出现的次数\n");
	char tmp_word[WORD_MAX_LENGTH];
	traverse_tree(tree,tmp_word,0);
	display();

	return 0;
}

转载请标明源博客:)

你可能感兴趣的:(struct,Blog,tree,null,insert)