前言
本程序来自于K&R的《C程序设计语言》一书中的练习1-13,原题目要求绘制水平和垂直两个方向的直方图。
思路
看到问题先想如何存储,本题使用数组去存放不同长度单词的数量就可以了,不同的下标表示不同的长度,注意要限定最大长度,以确定数组的大小。
至于如何统计单词数量和单词长度,该练习题前面几页已经给出了大概的程序,稍作修改即可。
水平直方图比较简单,两次循环即可。垂直直方图的绘制,我首先统计了数量的最大值,即直方图中最高的那个柱子的高度,根据该参数逐层绘制垂直直方图。下面是代码及运行结果:
代码
/*
* Author: LiYuqi
* Date: 2023/7/16
* Description: 统计输入的单词个数,并根据单词长度绘制直方图,最大长度此处限定为MAXLENGTH.
*/
#include <stdio.h>
#define IN 1 /* 在单词内部 */
#define OUT 0 /* 在单词外部 */
#define MAXLENGTH 12 /* 允许的最大单词长度 */
int main()
{
int length[MAXLENGTH]; /* 记录长度的数组 */
int c, wordNum, wordLength, maxNum, state;
state = OUT;
maxNum = -1; /* maxNum用于记录单词长度最多的数量,以方便垂直直方图的绘制*/
wordNum = wordLength = 0;
for (int i = 0; i < MAXLENGTH; i++) {
length[i] = 0;
}
while ((c=getchar()) != EOF) {
if (c == ' ' || c == '\n' || c == '\t') {
state = OUT;
if (wordLength != 0 && wordLength <= MAXLENGTH) {
++length[wordLength-1]; //由于不存在长度为0的单词,所以长度从1开始,下标=长度-1.
maxNum = length[wordLength-1]>maxNum? length[wordLength-1]: maxNum;
}
wordLength = 0;
}
else {
if (state == OUT) ++wordNum;
state = IN;
++wordLength;
}
}
printf("\n单词总数为:%d\n", wordNum);
printf("各单词的长度直方图为:\n");
/* 水平直方图 */
for (int i = 0; i < MAXLENGTH; i++) {
printf("%2d: ", i+1);
for (int j = 0; j < length[i]; j++) {
printf("*");
}
printf("\n");
}
/* 垂直直方图 */
printf("--------------分割线--------------\n");
for (int i = maxNum; i > 0; i--)
{
for (int j = 0; j < MAXLENGTH; j++)
{
if (length[j] - i >= 0) {
printf("* ");
--length[j];
} else {
printf(" ");
}
}
printf("\n");
}
for (int i = 0; i < MAXLENGTH; i++)
{
printf("%d ", i+1);
}
return 0;
}