1. 要求: 编写一个程序, 打印输入中单词长度的直方图. 水平方向的直方图学校录取容易绘制, 垂直方向的直方图则要困难些.
2. 水平直方图和垂直直方图.
1. 水平方向的直方图:
-
清楚直方图的定义: 又称质量分布图,是一种统计报告图,由一系列高度不等的纵向条纹或线段表示数据分布的情况。 一般用横轴表示数据类型,纵轴表示分布情况.
-
单词长度的直方图, 就是打印输入单词的长度.
-
水平方向的, 容易, 打印这个单词的长度就可以.
-
需要注意: 单词组成的字符个数不能超过MAXHIST20位, 暂时可以这么定义, 超出这20位用X表示.
-
统计单词的数量MAXWORDS最多15个, 使用数组来存储单词长度.
-
读取单词的字符长度练习1-12更改下即可得到.
2. 垂直直图.
-
使用数组来存单词长度
-
说明打印规则, 在第0行时, w1列打印空格还是*号, 取决于(HIST-w1长度) 和 当前行row比较, 大于当前行则打印空格, 小于等于则打印*号. 为何从0开始, 数组是从0开始. 下面举例HIST是4, w3单词的长度是2, 在第0行时, w1列是, 4-2 >0 则打印空格.
-
考虑到有些单词长度可能超出限制,如果有则打印X, 判断逻辑(单词长度>HIST) && 当前不在(row-1)行打印空格, 否则打印X.
-
为防止数组越界, 需要if(sum<MAXWORDS), 在单词数组内才进行计算字符数.
row
0
1 *
2 * * *
3 * * * X
w1 w2 w3 w4 (col)
3. 代码.
1. 随便统计了多少个单词, 可计算出多少个单词未打印.
2. clion Signal: SIGABRT 错误, 一般是数组越界.
#include <stdio.h>
#define MAXHIST 20
#define MAXWORDS 15
#define IN 1
#define OUT 0
int main()
{
int a[MAXWORDS];
int input;
int sum; // 单词个数
int row; // 行
int col; // 列
int flag;
row = col = sum = 0;
flag = OUT;
for(row=0;row<MAXWORDS;row++){
a[row] = 0;
}
while( (input=getchar()) != EOF){
if(input != ' ' && input != '\n' && input != '\t'){
flag = IN;
if(sum<MAXWORDS){
a[sum] ++;
if(a[sum] > MAXHIST){
continue;
}
}else{
continue;
}
}else{
if(flag == IN){
flag = OUT;
sum ++;
continue;
}
else{
continue;
}
}
}
for(row=0;row<MAXWORDS;row++){
if(row == 0){
printf("开始打印最多前15个单词的直方图\n");
}
printf("%3d|", row+1);
for(col=0;col<a[row];col++){
if(a[row] > MAXHIST){
printf("X");
break;
}
printf( "-" );
}
printf("\n");
if(row == ( MAXWORDS-1 )){
printf( "ALIAS: X MEANS THIS WORD OVER MAXHIST%d\n", MAXHIST );
}
}
if(sum > 15){
printf( "还有%d个单词未打印出直方图\n",sum-15 );
}
for(row=0;row<MAXHIST;row++){
if(row == 0){
printf("开始打印最多前15个单词的直方图\n");
}
for(col=0;col<MAXWORDS;col++){
if(a[col]>MAXHIST && row != (MAXHIST-1)){
printf(" ");
}else if(a[col] > MAXHIST && row == (MAXHIST -1)){
printf(" X");
}else if(a[col] <= MAXHIST){
if(MAXHIST-a[col]> row ){
printf(" ");
}else{
printf(" *");
}
}
}
printf("\n");
}
for(row=0;row<MAXWORDS;row++){
/*printf("hello");*/
printf("%3d", row+1);
}
return 0;
}