2014年07月30日

C#でコード中の文字の頻度分析

   このエントリーをはてなブックマークに追加 Clip to Evernote
どう書く?orgに感謝を込めて」シリーズ その29

■問題 (出題者:crane さん)
プログラムコード中の文字の頻度は言語によって相当にばらつきがあると思います。ある言語はピリオドが頻出するとか、別の言語はカッコの頻出頻度が高い、とか。そこで、
  • 文字の頻度解析をするプログラムを作成し、
  • 適当なプログラムに対して実行し、結果を出力して、そのような頻度になっている理由を教えてください。
(その言語で書かれた「典型的な」プログラムコード、といえるようなものがあると良いのですが・・) 簡単すぎるという方は、複数文字にしてみたり単語の頻度にしてみてください。

参考;Wikipedia 頻度分析 http://ja.wikipedia.org/wiki/%E9%A0%BB%E5%BA%A6%E5%88%86%E6%9E%90

これはDictionaryクラスの出番ですね。 頻度分析を行うCharFreequencyクラスを定義してみました。
受け取る型をstringp[] にするか、string にするか迷いましたが、 単純な string にしました。File.ReadAllText 使えば、一発で string として取得できますからね。

頻度分析する際は、制御文字とWhiteSpaceは除いていますが、IsWhiteSpace だけでも問題はないですね。たぶん...

■C#で書いたコード
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;

namespace Doukaku.Org {
    class Program {
        static void Main(string[] args) {
            CharFrequency cd = new CharFrequency(File.ReadAllText(args[0]));  // C#はargs[1]ではなくargs[0]
            var dict = cd.Analyze();            

            // Top20だけを表示
            var total = dict.Sum(x => x.Value);
            foreach (var d in dict.OrderByDescending(x => x.Value).Take(20)) {
                Console.WriteLine("{0} = {1},  {2:#0.#0}%", d.Key, d.Value, d.Value * 100.0 / total);
            }
            Console.ReadLine();
        }
    }

    class CharFrequency {
        private string text;
        public CharFrequency(string s) {
            text = s;
        }

        public Dictionary<char, int> Analyze() {
            var dict = new Dictionary<char, int>();
            foreach (var c in text) {
                if (char.IsControl(c) || char.IsWhiteSpace(c))
                    continue;
                if (dict.ContainsKey(c))
                    dict[c]++;
                else
                    dict[c] = 1;
            }
            return dict;
        }
    }
}
あるソースを 実行してみたところ、以下のような結果となりました。

t = 1602,  8.30%
e = 1594,  8.25%
i = 923,  4.78%
n = 788,  4.08%
s = 729,  3.78%
r = 717,  3.71%
a = 715,  3.70%
m = 681,  3.53%

set, get, return, true. int, while, string, private, foreach system など、C#では、t や e を含む単語が多いですからね。
でも、通常の英文でも t や e は多そうですね。


 

この記事へのトラックバックURL

http://trackback.blogsys.jp/livedoor/gushwell/52378819