1. 要求: 编写一个程序, 打印输入中单词长度的直方图. 水平方向的直方图学校录取容易绘制, 垂直方向的直方图则要困难些.

2. 水平直方图和垂直直方图.

1. 水平方向的直方图:

  1. 清楚直方图的定义: 又称质量分布图,是一种统计报告图,由一系列高度不等的纵向条纹或线段表示数据分布的情况。 一般用横轴表示数据类型,纵轴表示分布情况.

  2. 单词长度的直方图, 就是打印输入单词的长度.

  3. 水平方向的, 容易, 打印这个单词的长度就可以.

  4. 需要注意: 单词组成的字符个数不能超过MAXHIST20位, 暂时可以这么定义, 超出这20位用X表示.

  5. 统计单词的数量MAXWORDS最多15个, 使用数组来存储单词长度.

  6. 读取单词的字符长度练习1-12更改下即可得到.

2. 垂直直图.

  1. 使用数组来存单词长度

  2. 说明打印规则, 在第0行时, w1列打印空格还是*号, 取决于(HIST-w1长度) 和 当前行row比较, 大于当前行则打印空格, 小于等于则打印*号. 为何从0开始, 数组是从0开始. 下面举例HIST是4, w3单词的长度是2, 在第0行时, w1列是, 4-2 >0 则打印空格.

  3. 考虑到有些单词长度可能超出限制,如果有则打印X, 判断逻辑(单词长度>HIST) && 当前不在(row-1)行打印空格, 否则打印X.

  4. 为防止数组越界, 需要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;
}