第9回の目標:プログラミングを通してデータの圧縮/展開の概念を学ぶ
デジタルデータの内容をなるべく保ちながら、データ量を減らすことをデータの圧縮という。
逆に圧縮されたデータを元に戻すことをデータの展開やデータの解凍という。
展開したときに、完全に元に戻るタイプの圧縮を可逆圧縮、完全に元にもどらないタイプの圧縮を非可逆圧縮という。
実際に使われる圧縮/展開のアルゴリズムには複雑なものもあるが、ここでは可逆圧縮のうちの簡単なアルゴリズムを扱うことにする。
以下のような圧縮/展開のルールを考える。
例題1 圧縮前のデータが1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1 であるとすると、圧縮後のデータはどうなるか。,で区切って表せ。
例題2 圧縮後のデータが1, 2, 0, 4, 1, 3, 0, 2 であるとすると、圧縮前のデータは何であったか。,で区切って表せ。
配列の〇番目に値を代入するという、今まで扱ってきた方法でも配列に値を追加することができるが、もう少し簡単な方法がある。
let array = []; // ちなみにarrayは配列の意味 array.push(5); array.push(6); array.push(7); array.push(8);
上のコードを実行すると、arrayは [5, 6, 7, 8] になる。つまり、pushしたものは配列の末尾に挿入される。このコードと下のコードは同じ結果になる。
let array = []; array[0] = 5; // これが配列の〇番目に値を代入するという今までの書き方 array[1] = 6; array[2] = 7; array[3] = 8;
例題3 変数 array0903 が既に宣言され、配列として初期化されている([] が代入されている)とする。pushを用いてこの配列に30個の0を挿入せよ。
また、配列名.length で配列の長さを取得できる。下のコードではxに4が代入される。
let array = ["りんご", "ばなな", "柿", "みかん"]; let x = array.length;
今回のルールにおける、展開のアルゴリズムを考える。
今回のルールで圧縮されたデータは、0番目、2番目、4番目・・・が元データの1 or 0を表し、1番目、3番目、5番目・・・は並ぶデータの個数を表す。
例題4 圧縮後のデータが 変数 array0904 に保存されている。これを展開したデータをexpand0904に格納せよ。変数expand0904は既に[]で初期化されているとする。
下のコードはヒントである。
let i,j;
// 配列のデータ2つ分で意味を成すから、j を2ずつ大きくして繰り返す
for (j = 0; j < array0904.length; j = j + 2) {
expand0904.push( 配列に追加するものを指定する ); //これを必要な回数分繰り返す
}
0,1が並ぶデータを画像データだと思えば、今回の話は画像の圧縮/展開の話だと思える。
例題5 array0905は配列であり、今回のルールで圧縮されたデータが格納されている。第8回の画像処理と同様に0を白、1を黒だとし、縦横にそれぞれ40個の正方形を並べて画像として表示せよ。以下にElementIdが"ID1255"である400×400のキャンバスがある。fillSquare関数は既に定義されているとする。