Huffman符号の復習をしてみた
※追記:一部、記事の解説に間違いがあった。詳細は以下を参照のこと。
※追記ここまで
思うところがあってHuffman符号について復習した。Huffman符号は、与えたテキスト内の文字の分布によって、それぞれの文字に割り振るbit列を決める。出現頻度が高い文字ほどbit列が短くなる。具体的には頻度の高い文字から順番に0, 10, 110, ... , 1...10, 1...11と符号を割り振っていく。
詳細はWikipediaとかを見ると良い。
折角なので入力したテキストから各文字にbit列を割り振るperlスクリプトを書いてみた。
#!/usr/local/bin/perl use strict; use warnings; my %freq; while (<>) { chomp; my @a = split(//); foreach (@a) { $freq{$_}++; } } my $size = scalar(keys %freq); my @sorted = sort{$freq{$a}<=>$freq{$b}}(keys %freq); my %code; foreach (@sorted) { $code{$_} = ""; } for (my $i = 1; $i < $size; $i++) { $code{$sorted[$i]} = "0$code{$sorted[$i]}"; for (my $j = 0; $j < $i; $j++) { $code{$sorted[$j]} = "1$code{$sorted[$j]}"; } } foreach (@sorted) { print "$_($freq{$_}): $code{$_}\n"; }
例えば
$$ cat test.txt abracadabra
というテキストの各文字をHuffman符号化してみる。
$$ ./huffman.pl < test.txt c(1): 1111 d(1): 1110 r(2): 110 b(2): 10 a(5): 0
となった。頻度が高い文字ほど短いbit列が割り振られているのがわかる。めでたし。