K&R演習[1-14]

課題

入力中の異なる文字の頻度をヒストグラムにプリントするプログラムを書け。

方針

「入力中の異なる文字の頻度をヒストグラムにプリントする」と解釈する。

回答

#include <stdio.h>

const int CNT = 10;         // 出現回数
const int N_CHAR = 26;      // アルファベット数

void print_histogram(int *cnt, char start); // ヒストグラム表示

/**
 * @fn      main
 * @brief   アルファベット別の出現回数をヒストグラムにして表示する
 * @param   なし
 * @return  なし
 * @detail
 */
int main(void)
{
    int cntL[N_CHAR], cntS[N_CHAR], i, c;

    for (i = 0; i < N_CHAR; i++) {
        cntL[i] = 0;    // 大文字カウント
        cntS[i] = 0;    // 小文字カウント
    }

    while ((c = getchar()) != EOF) {        // ファイル終端まで

        if (('A' <= c) && (c <= 'Z')) cntL[c - 'A']++;
        if (('a' <= c) && (c <= 'z')) cntS[c - 'a']++;
        if (c == '\n') {                    // 改行でヒストグラム印字
            printf("------- histogram -------\n");  // タイトル
            print_histogram(cntL, 'A');     // ヒストグラム印字
            print_histogram(cntS, 'a');     // ヒストグラム印字

            // 次に備えて初期化
            for (i = 0; i < N_CHAR; i++) {
                cntL[i] = 0;    // 大文字カウント
                cntS[i] = 0;    // 小文字カウント
            }
        }
    }
}

/**
 * @fn      ヒストグラム印字
 * @brief   
 * @param   なし
 * @return  なし
 * @sa      
 * @detail  
 */
void print_histogram(int *cnt, char start)
{
    char i, j;

    // 大文字
    for (i = CNT; i >= 1; i--) {            // 回数
        printf("%2d", i);                   // 縦軸

        for (j = 0; j < N_CHAR; j++) {
            if (*(cnt + j) >= i) {          // 現在の回数以上であれば
                printf("  *");              // 文字を表示する
            } else {
                printf("   ");              // 空白を表示する
            }
        }
        printf("\n");
    }
    printf("  ");                           // 横軸(アルファベット)
    for (j = 0; j < N_CHAR; j++) {          // 
        printf("  %c", j + start);          // 大文字
    }
    printf("\n");
}

実行内容

It is a worthy ambition to do well whatever one does.

実行結果

------- histogram -------
10
 9
 8
 7
 6
 5
 4
 3
 2
 1                          *
    A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z
10
 9
 8
 7
 6                                            *
 5              *                             *              *
 4              *                             *              *
 3  *           *           *                 *              *        *
 2  *        *  *        *  *        *     *  *        *  *  *        *
 1  *  *     *  *        *  *        *  *  *  *        *  *  *     *  *     *
    a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z

補足

課題の日本語の意味がよく分からないので、自分なりに解釈した。まともな日本語で書いて欲しい。