文字のヒストグラム

30分プログラム、その423。文字のヒストグラムを作ってみよう。
うちの弟が学校の課題で、文字列をいれると使っているアルファベットの数を表示するプログラムをCで作っていた。

$ ./a.out
文字列を入力してください: hoge

使っているアルファベットは:
e ... 1
g ... 1
h ... 1
o ... 1

わりとおもしろそうだったので、ボクもマネしてみた。ただし、Schemeで。

使い方

$ gosh word-hist.scm hoge
e ... 1
g ... 1
o ... 1
h ... 1

ソースコード

#! /opt/local/bin/gosh
;; -*- mode:scheme; coding:utf-8 -*-
;;
;; word-hist.scm -
;;
;; Copyright(C) 2008 by mzp
;; Author: MIZUNO Hiroki / mzpppp at gmail dot com
;; http://howdyworld.org
;;
;; Timestamp: 2008/11/26 23:26:17
;;
;; This program is free software; you can redistribute it and/or
;; modify it under MIT Lincence.
;;
(use gauche.collection)
(use srfi-1)

(define (word-hist . words)
  (sort
   (map (lambda (xs) (cons (car xs) (length xs))) 
	(group-collection (append-map string->list words)))
   (lambda (a b) (compare (cdr a) (cdr b)))))

(define (main args)
  (for-each
   (lambda (c)
     (format #t "~A ... ~D\n" (car c) (cdr c)))
   (apply word-hist (cdr args))))

ソースコード(C言語)

いちおうC言語でも書いたので、そちらも。

#include <stdio.h>
char lower(char c){
  if('A' <= c  && c <= 'Z'){
    return c - 'A' + 'a';
  }else{
    return c;
  }
}

int main(int argc, char *argv[]) {
  int hists[26] = {};

  for (int i = 1; i < argc; ++i) {
    char* p = argv[i];

    while(*p != '\0'){
      char c = lower(*p);
      if('a' <= c && c <= 'z'){
	hists[c - 'a'] ++;
      }
      ++p;
    }
  }

  for(int i = 0; i < 26; ++i){
    if(hists[i] != 0){
      printf("%c ... %d\n",i+'a',hists[i]);
    }
  }
  return 0;
}