K&R_6.5用二叉树统计单词出现的次数

因为预先不知道出现的单词列表,无法方便地排序并使用折半查找;也不能分别对输入中的每个单词都执行一次线性查找,开销太大-->O(n^n)。

所以考虑使用二叉树的数据结构(O(n*logn))来组织这些单词,实现如下:

-----

/*
 * My practice of K&R 6.5
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define MAXWORD 100

/* a binary tree node */
typedef struct tnode_ {
	char *word;
	int count;
	struct tnode_ *left;
	struct tnode_ *right;
} tnode;

void print_tree(tnode *root);
tnode *add_tree(tnode *root, char *word);
void free_node(tnode *root);

char *copy_string(char *s) {
	char *p = (char *)malloc(strlen(s)+1);
	if(p != NULL) {
		strcpy(p, s);
	}

	return p;
}

tnode *add_tree(tnode *p, char *word) {
	int result;
	if(p == NULL) {
		p = (tnode *)malloc(sizeof(tnode));
		p->word= copy_string(word); // Attention !
		p->count = 1;
		p->left = NULL;
		p->right = NULL;
	}
	else {
		result = strcmp(word, p->word);
		if(result < 0) {
			p->left = add_tree(p->left, word);
		}
		else if(result > 0) {
			p->right = add_tree(p->right, word);
		}
		else {
			p->count++;
		}
	}

	return p;
}

void print_tree(tnode *p) {
	if(p) {
		print_tree(p->left);
		printf("%s\t : %4d\n", p->word, p->count);
		print_tree(p->right);
	}
}

void free_node(tnode *p) {
	if(p) {
		free_node(p->left);
		free_node(p->right);
		free(p->word);
		free(p);
	}
}

int getword(char *word, int n) {
	int c;
	char *w = word;

	while(isspace(c = getchar())) {
		;
	}
	if(c != EOF) {
		*w++ = c;
	}
	if(!isalpha(c)) {
		*w = '\0';
		return c;
	}
	while(n > 0) {
		c = getchar();
		if(isalnum(c)) {
			*w++ = c;
		}
		else {
			break;
		}
		n--;
	}

	*w = '\0';
	return w[0];
}

int main() {
	tnode *root = NULL; // 指针一定要初始化为NULL
	char word[MAXWORD];

	while((getword(word, MAXWORD)) != EOF) {
		if(isalnum(word[0])) {
			root = add_tree(root, word);
		}
	}

	print_tree(root);

	free_node(root);

	return 0;
}

github:https://github.com/wusuopubupt/LearningC/blob/master/K%26R/chp6/binary_tree_word_counter.c

参考:http://blog.csdn.net/roma823/article/details/6669925

时间: 2024-10-12 08:44:10

K&R_6.5用二叉树统计单词出现的次数的相关文章

C语言实现二叉树-利用二叉树统计单词数目

昨天刚参加了腾讯2015年在线模拟考: 四道大题的第一题就是单词统计程序的设计思想: 为了记住这一天,我打算今天通过代码实现一下: 我将用到的核心数据结构是二叉树: (要是想了解简单二叉树的实现,可以参考我的另一篇文章:http://www.cnblogs.com/landpack/p/4783120.html) Problem 我需要统计的单词是在程序直接硬编码的: 这样做得原因是省略了文件输入输出所带来的困惑: 我的每篇文章,一般只说一个主题: 这样也方便我日后复习: Solution 首先

N个任务掌握java系列之统计一篇文章中单词出现的次数

问题:统计一篇文章中单词出现的次数 思路: (1)将文章(一个字符串存储)按空格进行拆分(split)后,存储到一个字符串(单词)数组中. (2)定义一个Map,key是字符串类型,保存单词:value是数字类型,保存该单词出现的次数. (3)遍历(1)中得到的字符串数组,对于每一个单词,考察Map的key中是否出现过该单词,如果没出现过,map中增加一个元素,key为该单词,value为1(第一次出现): 如果,在map的key中发现了该单词,则通过key找到对应的value(单词出现的次数)

NOIP2001 统计单词个数

题三 统计单词个数(30分) 问题描述 给出一个长度不超过200的由小写英文字母组成的字母串(约定;该字串以每行20个字母的方式输入,且保证每行一定为20个).要求将此字母串分成k份(1<k<=40),且每份中包含的单词个数加起来总数最大(每份中包含的单词可以部分重叠.当选用一个单词之后,其第一个字母不能再用.例如字符串this中可包含this和is,选用this之后就不能包含th). 单词在给出的一个不超过6个单词的字典中. 要求输出最大的个数. 输入格式 去部输入数据放在文本文件input

codevs 1040 统计单词个数

1040 统计单词个数 2001年NOIP全国联赛提高组  题目等级 : 黄金 Gold 题目描述 Description 给出一个长度不超过200的由小写英文字母组成的字母串(约定;该字串以每行20个字母的方式输入,且保证每行一定为20个).要求将此字母串分成k份(1<k<=40),且每份中包含的单词个数加起来总数最大(每份中包含的单词可以部分重叠.当选用一个单词之后,其第一个字母不能再用.例如字符串this中可包含this和is,选用this之后就不能包含th)(管理员注:这里的不能再用指

Hadoop读书笔记(五)MapReduce统计单词demo

Hadoop读书笔记(一)Hadoop介绍:http://blog.csdn.net/caicongyang/article/details/39898629 Hadoop读书笔记(二)HDFS的shell操作:http://blog.csdn.net/caicongyang/article/details/41253927 Hadoop读书笔记(三)Java API操作HDFS:http://blog.csdn.net/caicongyang/article/details/41290955

洛谷 【P1026】统计单词个数

P1026 统计单词个数 题目描述 给出一个长度不超过200的由小写英文字母组成的字母串(约定;该字串以每行20个字母的方式输入,且保证每行一定为20个).要求将此字母串分成k份(1<k<=40),且每份中包含的单词个数加起来总数最大(每份中包含的单词可以部分重叠.当选用一个单词之后,其第一个字母不能再用.例如字符串this中可包含this和is,选用this之后就不能包含th). 单词在给出的一个不超过6个单词的字典中. 要求输出最大的个数. 输入输出格式 输入格式: 每组的第一行有二个正整

2001年 统计单词个数

统计单词个数 题目描述 给出一个长度不超过200的由小写英文字母组成的字母串(约定;该字串以每行20个字母的方式输入,且保证每行一定为20个).要求将此字母串分成k份(1<k<=40),且每份中包含的单词个数加起来总数最大(每份中包含的单词可以部分重叠.当选用一个单词之后,其第一个字母不能再用.例如字符串this中可包含this和is,选用this之后就不能包含th)(管理员注:这里的不能再用指的是位置,不是字母本身.比如thisis可以算做包含2个is).单词在给出的一个不超过6个单词的字典

P1026 统计单词个数

P1026 统计单词个数 题目描述 给出一个长度不超过200的由小写英文字母组成的字母串(约定;该字串以每行20个字母的方式输入,且保证每行一定为20个).要求将此字母串分成k份(1<k<=40),且每份中包含的单词个数加起来总数最大(每份中包含的单词可以部分重叠.当选用一个单词之后,其第一个字母不能再用.例如字符串this中可包含this和is,选用this之后就不能包含th). 单词在给出的一个不超过6个单词的字典中. 要求输出最大的个数. 输入输出格式 输入格式: 每组的第一行有二个正整

NOIP200107统计单词个数

NOIP200107统计单词个数 难度级别: A: 编程语言:不限:运行时间限制:1000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 给出一个长度不超过200的由小写英文字母组成的字母串(约定;该字串以每行20个字母的方式输入,且保证每行一定为20个).要求将此字母串分成k份(1<k<=40),且每份中包含的单词个数加起来总数最大(每份中包含的单词可以部分重叠,但不能选出两个单词而它们的开始位置相同). 单词在给出的一个不超过6个单词的字典中.要求输出最大