[小西ホームページ]   [目次・索引]   [前の授業]   [次の授業]

コンピュータIIL(情報科学入門)第8回

目次
8.1 データ圧縮
8.1.1 符号化と復号
8.1.2 固定長符号
8.1.3 ランレングス符号
8.1.4 ハフマン符号
8.2 演習8
8.3 レポート課題
8.4 参考文献
索引
ASCII符号   一意的に復号化可能   可変長符号   固定長符号   語頭   語頭条件   データ圧縮   ハフマン符号   復号   符号化   ランレングス符号  

8.1 データ圧縮

8.1.1 符号化と復号

文字列などのデータを数種類の記号の列に変換することを、 符号化encoding ) と言います。 符号化されたデータを元に戻すことを、 復号decoding ) と言います。

コンピュータが使われるまでは、符号化は数字の列に変換することが多かったのですが、コンピュータでデータを処理する現在は、普通はビットの列に変換します。

符号化は、データを保存するときに行われます。 つまり、データは符号化されてビット列になり、各ビットがハード・ディスクの磁気状態などとして記録されます。 また、データを転送するときにも符号化が行われます。 各ビットは、銅線の電気信号などとして通信されます。

今回は、文字列の符号化について考えます。

文字の符号化で国際標準となっているのが、 ASCII符号ASCII code ) です。 以下は、ASCII符号の一部です。

表 8.1  ASCII符号(一部)
文字 符号 文字 符号 文字 符号


@ 0100 0000 ` 0110 0000
! 0010 0001 A 0100 0001 a 0110 0001
" 0010 0010 B 0100 0010 b 0110 0010
# 0010 0011 C 0100 0011 c 0110 0011
$ 0010 0100 D 0100 0100 d 0110 0100
% 0010 0101 E 0100 0101 e 0110 0101
& 0010 0110 F 0100 0110 f 0110 0110
' 0010 0111 G 0100 0111 g 0110 0111
( 0010 1000 H 0100 1000 h 0110 1000
) 0010 1001 I 0100 1001 i 0110 1001
* 0010 1010 J 0100 1010 j 0110 1010
+ 0010 1011 K 0100 1011 k 0110 1011
, 0010 1100 L 0100 1100 l 0110 1100
- 0010 1101 M 0100 1101 m 0110 1101
. 0010 1110 N 0100 1110 n 0110 1110
/ 0010 1111 O 0100 1111 o 0110 1111
0 0011 0000 P 0101 0000 p 0111 0000
1 0011 0001 Q 0101 0001 q 0111 0001
2 0011 0010 R 0101 0010 r 0111 0010
3 0011 0011 S 0101 0011 s 0111 0011
4 0011 0100 T 0101 0100 t 0111 0100
5 0011 0101 U 0101 0101 u 0111 0101
6 0011 0110 V 0101 0110 v 0111 0110
7 0011 0111 W 0101 0111 w 0111 0111
8 0011 1000 X 0101 1000 x 0111 1000
9 0011 1001 Y 0101 1001 y 0111 1001
: 0011 1010 Z 0101 1010 z 0111 1010
; 0011 1011 [ 0101 1011 { 0111 1011
< 0011 1100 \ 0101 1100 | 0111 1100
= 0011 1101 ] 0101 1101 } 0111 1101
> 0011 1110 ^ 0101 1110 ~ 0111 1110
? 0011 1111 _ 0101 1111

符号化で重要なことは、復号して正確に元に戻ることです。 このことを、 一意的に復号化可能uniquely decodable ) と言います。 一意的に復号化可能であるためには、異なるデータは異なるビット列に符号化されなければなりません。

ASCII符号は一意的に復号化可能です。 なぜなら、ビット列を8ビットごとに区切ればよいからです。

例えば、文字列"ABC"は、

010000010100001001000011

と24ビットに符号化されます。 復号するときは、これを

01000001 01000010 01000011

と8ビットごとに区切り、それぞれを復号すれば、文字列"ABC"に戻ります。

8.1.2 固定長符号

符号化を工夫することによってビット列を短くすることを、 データ圧縮data compression ) と言います。 データによっては工夫の余地がないものもありますが、多くのデータは何らかの符号化によって圧縮可能です。

データ圧縮には多くのメリットがあります。 ハード・ディスクにより多くのデータが記録できますし、データを通信するときの時間や費用が節約できます。

今回は文字列のデータ圧縮を考えるわけですが、まず注目すべきなのは、文字列に現れる文字の種類です。 文字の種類が少なければ少ないほど、1文字をより短いビット列に符号化できます。 具体的には、次の表の通りです。

表 8.2  符号のビット長と符号化できる文字数
ビット長 文字数
1 2
2 4
3 8
4 16
5 32
6 64
7 128

例として、文字列"AAAAAAAABBBBBBCCCCDD"を圧縮します。 ASCIIで符号化しますと、160ビットになります。 一方、文字は"A", "B", "C", "D"の4種類しかありませんので、"A"を 00 , "B"を 01 , "C"を 10 , "D"を 11 と、1文字2ビットに符号化しますと、

00 00 00 00 00 00 00 00 01 01 01 01 01 01 10 10 10 10 11 11

と、40ビットに符号化されます。

なお、すべての文字を同じ長さのビット列に符号化する符号のことを、 固定長符号fixed-length code ) と呼びます。 固定長符号は一意的に復号化可能です。

8.1.3 ランレングス符号

ランレングス符号run-length code ) は、同じ文字が連続して現れるときに効果的な圧縮法です。 これは、上記の文字列"AAAAAAAABBBBBBCCCCDD"なら、これをいったん"8A6B4C2D"に変換してから符号化するものです。

変換結果を固定長符号で符号化しますと、文字の種類は元の4種類と数字の10種類ですので、次のように1文字4ビットに符号化できます。

表 8.3  ランレングス符号の符号化
文字 符号
0 0000
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
9 1001
A 1010
B 1011
C 1100
D 1101
E 1110
F 1111

したがって、

1000 1010 0110 1011 0100 1100 0010 1101

と、32ビットに符号化されます。 単純な固定長符号では40ビットでしたので、ランレングス符号によって、より圧縮されたことが分かります。

ランレングス符号では、元の文字列に数字が現れないようにする必要があります。 また、連続しない文字を"1E"のようにしますと、逆に長くなりますので、これは"E"のままにします。

8.1.4 ハフマン符号

上記の文字列"AAAAAAAABBBBBBCCCCDD"を並び替えた文字列"ABCACBABDAABCACBABDA"の圧縮を考えます。 ランレングス符号では圧縮できませんので、他の符号化を考えます。

方針は、よく現れる文字は短いビット列で符号化し、あまり現れない文字は長いビット列で符号化することです。 このような、文字によってビット列の長さを変える符号を、 可変長符号variable-length code ) と呼びます。

可変長符号は、一般的には一意的に復号化可能ではありません。 例えば、"A"を 0 , "B"を 01 , "C"を 10 に符号化しますと、 010 は"AC"にも"BA"にも復号されます。

一意的でないのは、"A"の符号 0 が"B"の符号 01 の語頭だからです。 ここで、 語頭prefix ) とは、先頭からの部分列のことです。 符号化は、どの文字の符号も他の文字の符号の語頭でないという、 語頭条件prefix condition ) を満たせば、一意的に復号化可能です。

可変長符号では、 ハフマン符号Huffman code ) が、一意的に復号化可能で、かつ最もよい圧縮法です。 以下にその作り方を示します。

まず、文字列における文字の出現頻度を調べます。 上記の文字列では、"A" = 8, "B" = 6, "C" = 4, "D" = 2 です。 次に、出現頻度の低いほうから2つを「合併」します。 なお、最も低いものが3つ以上ある場合は、その中から任意の2つを選びます。 また、最も低いものが1つあり、次に低いものが2つ以上ある場合は、最も低いものと、次に低いものの中から任意の1つを選びます。 この場合は、"C" = 4 と "D" = 2 を合併して、"C" + "D" = 6 とします。 この合併を、1つになるまで繰り返します。 この場合は、

"A" = 8, "B" = 6, "C" = 4, "D" = 2 "A" = 8, "B" = 6, "C" + "D" = 6
"A" = 8, "B" + ("C" + "D") = 12
"A" + ("B" + ("C" + "D")) = 20

です。 そして、合併の過程をトーナメント表にします。 この場合は、次のようになります。

ハフマン符号の構成
図 8.1  ハフマン符号の構成

最後に、トーナメント表の上からたどり、左側を 0 に、右側を 1 に対応させます。 この場合は、"A"は 0 , "B"は 10 , "C"は 110 , "D"は 111 です。 以上の手続きによって、並び替える前の文字列"AAAAAAAABBBBBBCCCCDD"は

0 0 0 0 0 0 0 0 10 10 10 10 10 10 110 110 110 110 111 111

と、38ビットに符号化されます。 もちろん、並び替えた後の文字列も、38ビットに符号化されます。

以上の結果をまとめますと、次のようになります。

表 8.4  色々な符号化による符号の長さ
文字列 固定長符号 ランレングス符号 ハフマン符号
"AAAAAAAABBBBBBCCCCDD" 40ビット 32ビット 38ビット
"ABCACBABDAABCACBABDA" 40ビット 80ビット 38ビット

ランレングス符号は特別な場合でしか圧縮できませんが、ハフマン符号は大抵の場合で圧縮できることが分かります。

例題1. 文字列"AAABBBCCDD"を固定長符号、ランレングス符号、およびハフマン符号で符号化し、符号の長さを比較してください。

解答例1. 固定長符号については、文字が4種類なので1文字2ビットで符号化して、符号の長さは20ビットになる。 ランレングス符号については、いったん"3A3B2C2D"に変換する。 文字と数字で14種類になるので、1文字4ビットで符号化して、符号の長さは32ビットになる。 ハフマン符号については、出現頻度の低い2つを順次合併していくと、

"A" = 3, "B" = 3, "C" = 2, "D" = 2 "A" = 3, "B" = 3, "C" + "D" = 4
"A" + "B" = 6, "C" + "D" = 4
("A" + "B") + ("C" + "D") = 10

となる。 したがって、"A"は 00 , "B"は 01 , "C"は 10 , "D"は 11 と符号化し、全体では

00 00 00 01 01 01 10 10 11 11

と、符号の長さは20ビットになる。


8.2 演習8

次の文字列を固定長符号、ランレングス符号、およびハフマン符号で符号化し、符号の長さを比較してください。

  1. "AAAAABBBCCDE"
  2. "AAAAABBCCDDE"
  3. "AAAABBBCCCDE"

8.3 レポート課題

今日の演習8の答案をメールで提出してください。 メールの差出人は学内のアドレス(b04a001@twcu.ac.jpなど)とし、メールの宛先はkonishi@twcu.ac.jpとします。 メールの本文には、学生番号、氏名、科目名、授業日(12月1日)を明記してください。


8.4 参考文献


[小西ホームページ]   [目次・索引]   [前の授業]   [次の授業]

2006年12月1日更新
小西 善二郎 <konishi@twcu.ac.jp>
Copyright (C) 2006 Zenjiro Konishi. All rights reserved.