プログラミング講座 第9回

第9回の目標:プログラミングを通してデータの圧縮/展開の概念を学ぶ

1.データの圧縮/展開

デジタルデータの内容をなるべく保ちながら、データ量を減らすことをデータの圧縮という。

逆に圧縮されたデータを元に戻すことをデータの展開データの解凍という。

展開したときに、完全に元に戻るタイプの圧縮を可逆圧縮、完全に元にもどらないタイプの圧縮を非可逆圧縮という。

実際に使われる圧縮/展開のアルゴリズムには複雑なものもあるが、ここでは可逆圧縮のうちの簡単なアルゴリズムを扱うことにする。

以下のような圧縮/展開のルールを考える。

例題1 圧縮前のデータが1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1 であるとすると、圧縮後のデータはどうなるか。,で区切って表せ。

結果:

例題2 圧縮後のデータが1, 2, 0, 4, 1, 3, 0, 2 であるとすると、圧縮前のデータは何であったか。,で区切って表せ。

結果:

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;
  

3.展開のアルゴリズム

今回のルールにおける、展開のアルゴリズムを考える。

今回のルールで圧縮されたデータは、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( 配列に追加するものを指定する ); //これを必要な回数分繰り返す
  }
  
結果:

4.画像を展開して表示しよう

0,1が並ぶデータを画像データだと思えば、今回の話は画像の圧縮/展開の話だと思える。

例題5 array0905は配列であり、今回のルールで圧縮されたデータが格納されている。第8回の画像処理と同様に0を白、1を黒だとし、縦横にそれぞれ40個の正方形を並べて画像として表示せよ。以下にElementIdが"ID1255"である400×400のキャンバスがある。fillSquare関数は既に定義されているとする。

第8回へ 目次へ 第10回へ