打印单词长度的直方图--C语言的多种实现

欢迎访问我的新博客:http://www.milkcu.com/blog/

原文地址:http://www.milkcu.com/blog/archives/1366959780.html

题目要求

该题摘自Kernighan的《C程序设计语言》第17页练习1-13。

编写一个程序,打印输入中单词长度的的直方图。水平方向的直方图比较容易绘制,垂直方向的直方图则要困难些。

经过这本C语言圣经第一章的调教,发现getchar()原来那么强大。

多种实现

方案一:

声明state变量,用来记录程序当前是否正位于一个单词之中,这样便于理解。

# include <stdio.h>
# define MAX 20
# define OUT 0
# define IN 1

int main(void)
{
	int length[MAX];
	int c;
	int vocl;
	int state = OUT;
	int i;
	
	for(vocl = 0; vocl < MAX; vocl++){
		length[vocl] = 0;
	}
	while((c = getchar()) != EOF){
		if(c != ' ' && c != '\t' && c != '\n'){
			if(state == OUT){
				vocl = 1;
			} else{
				vocl++;
			}
			state = IN;
		} else{
			length[vocl]++;
			vocl = 0;
		}
	}
	for(vocl = 0; vocl < MAX; vocl++){
		if(length[vocl] != 0){
			printf("%2d  ", vocl);
			for(i = 1; i <= length[vocl]; i++){
				putchar('*');
			}
			putchar('\n');
		}
	}
}

方案二:

将state省掉,原理同方案一,代码简单的同时也降低了可读性。

# include <stdio.h>
# define MAX 20
# define OUT 0
# define IN 1

int main(void)
{
	int length[MAX];
	int c;
	int vocl;
	int state = OUT;
	int i;
	
	for(vocl = 0; vocl < MAX; vocl++){
		length[vocl] = 0;
	}
	vocl = 0;  //vocl别忘了初始化 
	while((c = getchar()) != EOF){
		if(c != ' ' && c != '\t' && c != '\n'){
			vocl++;
		} else{
			length[vocl]++;
			vocl = 0;
		}
	} 

	for(vocl = 0; vocl < MAX; vocl++){
		if(length[vocl] != 0){
			printf("%2d  ", vocl);
			for(i = 1; i <= length[vocl]; i++){
				putchar('*');
			}
			putchar('\n');
		}
	}
}

方案三:

一种新的思路,用该字符是否为字母或连字符判断是否为一个单词,是程序更简单、更容易理解。

# include <stdio.h>
# define MAX 20
# define OUT 0
# define IN 1

int main(void)
{
	int length[MAX];
	int c;
	int vocl = 0;
	int state = OUT;
	int i;
	
	for(vocl = 0; vocl < MAX; vocl++){
		length[vocl] = 0;
	}
	vocl = 0; 
	while((c = getchar()) != EOF){
		if(c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z' || c == '-'){
			vocl++;
		} else{
			length[vocl]++;
			vocl = 0;
		}
	}

	for(vocl = 0; vocl < MAX; vocl++){
		if(length[vocl] != 0){
			printf("%2d  ", vocl);
			for(i = 1; i <= length[vocl]; i++){
				putchar('*');
			}
			putchar('\n');
		}
	}
}

方案四:

对应的参考书提供的一种解法,也使用了state确定程序状态。只是打印直方图的代码更加完善,但不管该长度的单词有无均打印一行,像我一样加个判断语句也是不错的选择。

# include <stdio.h>
# define MAX 20
# define MAXLENGTH 20
# define MAXHIST 15

int main(void){
	int length[MAX];  //存放某一单词长度单词个数的数组 
	int c;  //c=getchar() 
	int vocl = 0;  //记录某一单词的长度 
	int maxvalue;
	int len = 0;
	 
	for(vocl = 0; vocl < MAX; vocl++){
		length[vocl] = 0;
	}
	vocl = 0; 
	while((c = getchar()) != EOF){
		if(c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z' || c == '-'){
			vocl++;
		} else{
			length[vocl]++;
			vocl = 0;
		}
	}
	
	maxvalue = 0;
	for(vocl = 1; vocl < MAX; ++vocl){
		if(length[vocl] > maxvalue){
			maxvalue = length[vocl];
		}
	}
	for(vocl = 1; vocl < MAX; ++vocl){
		printf("%5d - %5d : ", vocl, length[vocl]);
		if(length[vocl] > 0){
			if((len = length[vocl] * MAXHIST / maxvalue) <= 0){
				len = 1;
			} 
		} else{
			len = 0;
		}
		while(len > 0){
			putchar('*');
			--len;
		}
		putchar('\n');
	}
}

垂直方向直方图

其实,打印垂直方向的直方图没有题目说的那么可怕,也许是我的思维过于简单。

# include <stdio.h>
# define MAX 20
# define MAXLENGTH 20

int main(void){
	int length[MAX];
	int c;
	int vocl = 0;
	int i;
	int r;
	
	for(vocl = 0; vocl < MAX; vocl++){
		length[vocl] = 0;
	}
	vocl = 0; 
	while((c = getchar()) != EOF){
		if(c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z' || c == '-'){
			vocl++;
		} else{
			length[vocl]++;
			vocl = 0;
		}
	}
	printf("0 1 2 3 4 5 6 7 8 9 10\n");
	for(r = 1; r < MAXLENGTH; r++){
		for(vocl = 0; vocl < MAX; vocl++){
			if(r <= length[vocl]){
				printf("* ");
			} else{
				printf("  ");
			}
		}
		putchar('\n');
	}
}
posted @ 2013-04-26 23:03  MilkCu  阅读(313)  评论(0编辑  收藏  举报