《C程序设计语言》Brain&Dennis著 练习1-13
控制台打印垂直直方图
代码附上:
/* P15 1.6 数组*/
#include <stdio.h>
#define IN 1 /* 在单词内 */
#define OUT 0 /* 在单词外 */
#define ASCII_SIZE 127 /* ascii字符个数 */
void print_all_char_times(){
/* 统计 数字、空白符、其他字符出现的次数 */
int c, nwhite, nother;
int ndigital[10];
for(int i = 0 ; i < 10; i++)
ndigital[i] = 0;
nwhite = nother = 0;
while( (c = getchar()) != EOF){
if( c >= '0' && c <= '9')
++ndigital[c-'0'];
else if( c == '\t' || c == ' ' || c == '\n')
++nwhite;
else
++nother;
}
printf("digitals = ");
for (int i = 0; i < 10; ++i)
{
printf("%d ", ndigital[i]);
}
printf(", white space = %d , other = %d \n", nwhite,nother);
}
/* 练习1-13 */
void print_word_len_hist(){
/* 打印单词长度的直方图
假设单词长度不超过15个字符
*/
int c, len, state, minLen,maxLen,maxNum; /* len存储每个单词的长度 */
int nw[16]; /* nw[0]不存有效数据 */
maxNum = 0; /* 最多的长度个数 */
maxLen = len = 0;
minLen = 16;
state = OUT;
for(int i = 0 ; i < 16; i++){
nw[i] = 0;
}
while(( c = getchar()) != EOF){
if( c != ' ' && c != '\t' && c != '\n'){
if(state == OUT){
state = IN;
len = 0; /* 从新单词开始 */
}
if(state == IN)
len++; /* len <= 15 */
}else{
if(state == IN){
state = OUT;
nw[len]++; /* 对应长度的单词个数加1 */
if(maxNum < nw[len])
maxNum = nw[len];
if(len < minLen)
minLen = len;
else if(len > maxLen)
maxLen = len;
}
}
}
printf("\n===================水平直方图=====================\n");
/* 绘制水平方向的直方图,只绘制最小长度到最大长度之间的直方图 */
for (int i = minLen; i <= maxLen ; ++i)
{
int num = nw[i]; /* 同一长度的单词数 */
printf("%3d ", i); /* 纵坐标:单词长度 */
for (int j = 0; j < num; ++j)
{
putchar('#');
}
putchar('\n');
}
printf("\n===================垂直直方图=====================\n");
for(int i = maxNum; i > 0; i--){
/* 从长度计数最多的(maxNum)开始,从上往下扫描。当前行i代表了,当前单词的长度个数,可理解为 值为i的一条水平扫描线
若某一个单词的计数大于等于i,说明该单词的个数超过了i的值,则打印‘ #’,否则说明计数没有达到i这条线,故输出空格
*/
for (int j = minLen; j <= maxLen; ++j)
{/* 每一行从最小的长度开始到最大的长度,进行判断,该长度的单词计数,是否超过或达到了当前的线i */
if(nw[j] >= i)
printf(" #");
else
printf(" ");
}
putchar('\n');
}
/* 打印横坐标 */
for (int j = minLen; j <= maxLen; ++j)
{
printf("%3d",j);
}
putchar('\n');
}
/* 练习1-14 */
void print_char_freq(){
/* 打印各个字符出现频率的直方图 */
int c;
int num[ASCII_SIZE]; /* ascii总共有127个字符 */
for (int i = 0; i < ASCII_SIZE; ++i)
{
num[i] = 0;
}
while((c = getchar()) != EOF){
num[c]++;
}
/* 水平直方图,垂直直方图参照练习1-13 */
/* 只打印有计数的字符 */
for (int i = 0; i < ASCII_SIZE; ++i)
{
if(num[i] > 0){
if( i == '\t') /* 显示制表符与换行符 */
printf(" \\t ");
else if( i == '\n')
printf(" \\n ");
else printf("%3c ", i);
for(int j = 0; j < num[i]; j++)
printf("#");
putchar('\n');
}
}
}
void main(){
// print_all_char_times();
print_word_len_hist();
// print_char_freq();
}
效果如下(请忽略乱码问题):