challenge コード中の文字の頻度分析

プログラムコード中の文字の頻度は言語によって相当にばらつきがあると思います。ある言語はピリオドが頻出するとか、別の言語はカッコの頻出頻度が高い、とか。そこで、

  • 文字の頻度解析をするプログラムを作成し、
  • 適当なプログラムに対して実行し、結果を出力して、そのような頻度になっている理由を教えてください。

(その言語で書かれた「典型的な」プログラムコード、といえるようなものがあると良いのですが・・)

簡単すぎるという方は、複数文字にしてみたり単語の頻度にしてみてください。

参考;Wikipedia 頻度分析

http://ja.wikipedia.org/wiki/%E9%A0%BB%E5%BA%A6%E5%88%86%E6%9E%90

出題者です。 こちらで用意していた回答は awk を使ったものでした。一応解説すると、組み込み変数FSを空にし、1行単位の文字毎に連想配列に格納しています。

1
2
3
4
5
6
7
8
9
# 1文字版
BEGIN { FS="" }
{ for (i=1; i<=NF; i++) ht[$i]++}
END { for (c in ht) print ht[c],c }

# 3文字版
BEGIN { FS="" }
{ for (i=1; i<=NF-2; i++) { ht[$i$(i+1)$(i+2)]++}}
END { for (c in ht) print ht[c],c }

Posted feedbacks - Common Lisp

ファイル内のアスキー文字の出現回数をまとめて表示させるようにしました。 仕様上は文字の内部表現がアスキーコードとは限らないので手抜きといえば手抜きかもしれません。

これを使って手元にあった xyzzy のソース src/*.cc と lisp/*.l を比較してみました。

C++ ではループなどでよく使いそうな + と等号、不等号 が多いです。 ブロックに使う {} もかなりの差がありました。 またネーミングの慣習から _ でも大きな差が出ました。

Lisp では予想通り () が多く、割合が C++ の二倍を超えています。 またマクロ文字として使われる # やクオート、バッククオートがたくさん出てきます。 それから \ や ^ の数が多かったのですが、これは正規表現で多用されているようなのでサンプルの性質によるところが大きそうです。 それ以外ではシンボル名に多用される - で大きな差が付いています。 同じくシンボル名に使われる * や format 指定子に使われる ~ も多めでした。

その他の記号類と大文字は C++ の方が多めになるようです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
(defun frequency (files)
  (let ((v (make-array 127 :initial-element 0)))
    (dolist (file files v)
      (with-open-file (s file :direction :input)
        (loop
          as c = (read-char s nil)
          while (characterp c)
          if (< (char-code c) 127) do (incf (svref v (char-code c))))))))

(defun print-frequency (files)
  (let ((v (frequency files)))
    (format t "~{~4@{~10S ~6D~^ ~}~%~}"
            (loop for n across v and i from 0
              if (plusp n) nconc (list (code-char i) n)))
    (format t "~&Total: ~D characters~%" (reduce #'+ v))))

Index

Feed

Other

Link

Pathtraq

loading...