您的位置:首页 > 编程语言 > C语言/C++

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

2013-04-26 23:03 525 查看
欢迎访问我的新博客: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');
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: