K&Rを読もう(6) 演習 1-13 単語の長さのヒストグラム表示

今回は激しくメンドクサイヨ。

ヒストグラムも定番っすね。

演習 1-13

入力された単語の長さをヒストグラム表示せよ。

これは応用でいける。

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#define MAX_COUNT 10

void print_histgram(int n)
{
    int i;
    for (i = 0; i < n; i++) {
        putchar('*');
    }
}

int main(void)
{
    int c, i;
    int length = 0;
    int count[MAX_COUNT];
    int over = 0; /* 溢れた時に入れる */

    for (i = 0; i < MAX_COUNT; i++) 
        count[i] = 0;
    
    while ((c = getchar()) != EOF) {
        if (isspace(c)) {
            if (length < MAX_COUNT)
                ++count[length];
            else
                ++over;
            length = 0;
            while(isspace((c = getchar())))
                ;
            if (c == EOF)
                break;
        } else
            ++length;
    }
    for (i = 1; i < MAX_COUNT; i++) {
        printf("%-2d   : %2d ", i, count[i]);
        print_histgram(count[i]);
        puts("");
    }
    printf("over : %2d ", over);
    print_histgram(over);
    puts("");
    exit(EXIT_SUCCESS);
}

長い単語の場合はoverに格納することにしました。

単語の長さ0(スペース)が入っているので1から表示します。

% ./ex-1-13 < ex-1-13.c
1    : 27 ***************************
2    : 12 ************
3    :  9 *********
4    :  1 *
5    :  4 ****
6    :  3 ***
7    :  3 ***
8    :  7 *******
9    :  7 *******
over : 13 *************

いい感じ。

縦書き

ヒストグラムを「縦書き」にせよ。

うは。

縦書きに専念するために色々仕様を取っぱらった。

縦書き変換のイメージは、

123    365
456 -> 258
789    147

こんな感じ。xとyを反転しただけではダメですね・・・。

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#define MAX_COUNT 30

int main(void)
{
    int c, i, j;
    int length = 0;
    int count[MAX_COUNT];
    char hist[MAX_COUNT][MAX_COUNT];

    for (i = 0; i < MAX_COUNT; i++)
        count[i] = 0;
    for (i = 0; i < MAX_COUNT * MAX_COUNT; i++)
        hist[0][i] = ' ';

    while ((c = getchar()) != EOF) {
        if (isspace(c)) {
            if (length < MAX_COUNT)
                ++count[length];
            length = 0;
            while(isspace((c = getchar())))
                ;
            if (c == EOF)
                break;
        } else
            ++length;
    }

    for (i = 1; i < MAX_COUNT; i++) {
        if (count[i] >= MAX_COUNT) /* バッファオーバーフローの防止 */
            count[i] = MAX_COUNT - 1;
        for (j = 0; j < count[i]; j++) {
            hist[MAX_COUNT - j][i - 1] = '*';
        }
    }
    for (i = 0; i < MAX_COUNT; i++) {
        hist[i][MAX_COUNT - 1] = '\0';
        printf("%s\n", hist[i]);
    }
    exit(EXIT_SUCCESS);
}

あんまりセクシーじゃないし、バグがあるかも。

で、実行結果。

% ./ex-1-13-2 < ex-1-13.c




*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
**
**
**
***
***
***    **
***    **
***    **
*** *  ** *
*** ***** *
*** ***** *   *

なんとか表示できた。