情報科学概論
2002.6-4



  1. 本日の作業内容

  2. 先週の宿題について

    6/3(月)夕方に発生したネットワークトラブルと先週の宿題に関する補足説明を しますので,アナウンスに注意してください.

  3. 出席確認

    出席に関する注意事項を説明しますので,その注意を良く聞いてから,電子メールにより出席の申告をしてください.「件名」は

    gairon 6-4 attend s0240**

    のように自分の学生番号を使って下さい.なお,入力ミスがあると出席として認 められないことになりますので,慎重に行ってください.文 字はすべて1バイト文字 (半角英数字) です.途中に入るスペースは一度に一個だけと してください.スペースは全部で3個です.また,**の部分は自分の学生番号の下二桁 です.

  4. 配列

    これまで配列について簡単に説明してはいます.また,主として ARGV について配列の操作を実行することを実習してきました.感じとして はつかんできていると思いますが,今回は配列についてより詳しく見ていく ことにしましょう.

    • 基本

      配列を作るには以下のようにします.

      
      ary = [2002, 6, 4]
      day = ["Tue", 6, "June", 2002]
      

      配列の和は要素の和となります.

      
      ary1 = [1,2,3]
      ary2 = [4,5,6]
      p ary1 + ary2
      

      要素の表示 (取り出し) は配列名に続けて[ ]内に序数を指定して行います.

      
      ary = [1,2,3]
      puts ary[1]
      

      要素の決まっていない配列を作成するには,空の[ ]を指定します.

      
      ary = []
      

      上記の配列は要素として nil が入っています.自己代入のようにそれ 自身の値も初期化されていないと処理できない場合はエラーが出ますので,注意 してください.初期値として0を代入した

      
      ary = [0, 0, 0]
      

      のようにすれば良いですが,要素の数が多いと面倒です.繰り返しを利用して0 を代入する方式の方が便利でしょう.

    • 文字列を自動分割して配列を作る

      画面に表示されたコマンドの結果などから要素を取り分けて配列に変換すること が可能です.それには,split と言うメソッドを使用します.次に例 を挙げてみましょう.これは,ターミナルで使用するコマンドである date と組み合わせて使用しています.

      
      date = `date -R`
      p date.split()
      

      ここでは新しいものがいくつかでてきました.まずは,それから順番に説明しま しょう.1行目に ` ` という引用符 (バッククオート) が登場します.この記号はキーボー ドの@のところにあり,Shiftキーを押したまま@を押すと入力できます.Ruby ではこの ` ` で囲ったものはターミナルのコマンドとして実行します. ここでは,現在時刻を表示するコマンドの出力結果が date という変 数に納められますが,自分で実行してみると分かるように,いくつかの文字列が スペースで区切られて並ぶようなものが変数に格納されます.

      2行名には split と言うメソッドが登場します.これは,英語の意味 を考えると分かると思いますが,「分割する」メソッドです.今の場合,() として分割に際して使用する文字を決めてい ません.そうすると,Rubyの方で適当に判断して 分割してくれます.今は,スペースが区切り文字 として自動的に使用されます.出力結果を確かめ てみてください.

    • 多重配列

      これまで,配列は要素が順番に一列に並んでいるイメージで考えてきました.し かし,配列は「多重」にすることが可能です.多重とはたとえば,次のように表 現します.

      
      ary = [[1, 2], 3, 4, [5, 6],[7, 8, 9, [10, 11, 12], 13]]
      

      上の例を考えると,まず,一番外側にある [] から見ていきます.す ると,その階層にある要素の数は

      [1, 2]
      3
      4
      [5, 6]
      [7, 8, 9, [10, 11, 12], 13]]
      の5個です.しかし,0番目の要素は配列であり, その中には要素が2つあります.4番目の要素はそれ自体が2重配列です.列挙す ると次のようになります.

      7
      8
      9
      [10, 11, 12]
      13
      まず,5個の要素の階層の配列があり,3番目は要素を3個持つ配列です.

      このような多重配列の応用例としては,「行列」があります.2行2列の行列は次 のようなものになります.

      
      ary = [[1, 2], [3, 4]]
      

      上の配列の要素を順番にすべて表示するスクリプトはどうなるでしょうか.基本 となる階層には要素は2つですが,そのそれぞれの要素にまた2つの要素が含まれ ています.0番目の要素のその中のさらに0番目が1ですし,1番目の要素の0番目 は3です.このように,要素を指定する序数が2個必要になっています.では,ス クリプトで見てみましょう.

      
      ary = [[1, 2], [3, 4]]
      for i in 0..1
        for j in 0..1
          puts ary[i][j]
        end
      end
      

      上のような2重のループでは,まず,i に0が入り,次に j について0と1の場合を実行します.j に関するループが終了すると, 次に i の値を1に増やしてまた,j について,0と1を取り出 します.

    • 多重配列の行列演算への応用

      まずは,単純な例として3行3列の行列の転置行列を求めてみましょう.次のよう なスクリプトが考えられます.

      
      a = [[1,2,3],[4,5,6],[7,8,9]]
      b = [[],[],[]]
      
      for i in 0..2
        for j in 0..2
          b[i][j] = a[j][i]
        end
      end
      
      p b
      

      次の例は配列を利用した行列の積を計算するスクリプトです.動作を考えてみま しょう.

      
      #matrix.rb
      a = [[1,2],[3,2]]
      b = [[2,3],[5,1]]
      c = [[],[]]
      
      for i in 0..1 do
        for j in 0..1 do
          c[i][j] = a[i][j].to_i * b[j][j].to_i + a[i][(j+1)%2].to_i * b[(j+1)%2][j].to_i
        end
      end
      
      p c
      

      二つの行列 a b は次のような行列の配列表記です.

      それらの積になる予定の行列 c をあらかじめ用意しますが,空の多重 配列定義は上のように行えます.

      次の部分は実際の計算ですが,ご存じのように行列の積は次のように定義されて います.

      c11=a11b11+a12b21
      c12=a11b12+a12b22
      c21=a21b11+a22b21
      c22=a21b12+a22b22

      この式を全部スクリプトに記述して計算することも出来ますが,規則性を見つけ て繰り返しを利用する方がすっきりします.そのために,ちょっと並び替えてみ ましょう.

      c11=a11b11+a12b21
      c12=a12b22+a11b12
      c21=a21b11+a22b21
      c22=a22b22+a21b12

      各式とも第一項の規則性は分かりやすくなっています.問題は第二項の規則性で すが,cの2番目の添字が1であれば2,2であれば1になることに気づくでしょうか.それ が分かると,そのような数字を作れば良いことになります.そのために, 「剰余」の考え方が使用されています.なぜなのか,考えてみると参考に なるでしょう.

    • 表データの読み込みを配列にする応用

      次のようなデータが record.txt という名前であるとします.

      Name English Mathematics Physics
      A 90 80 80
      B 65 50 55
      C 95 40 30
      D 70 90 90
      E 76 100 100

      これは5人の学生の英語,数学,物理のテストの点数です.各項目間は空白文字 (スペース) により区切られています.これから,各学生の 平均得点を求めたり,今日ごとの平均点を求めたりしてみましょう.スクリプト を以下のようにしてみます.

      
      NAME = ["A", "B", "C", "D", "E"]
      CLASS = ["English", "Mathematics", "Physics"]
      score = [[],[],[],[],[],[]]
      total1 = []
      total2 = []
      
      k = 0
      while line = ARGF.gets
        ary = line.split()
        n = 0
        for j in 0..3
            score[k][j] = ary[n]
            n += 1
        end
        k += 1
      end
      
      # Average of each student
      
      for i in 0..4
        total1[i] = 0
      end
      
      for i in 0..4
        for j in 1..3
          total1[i] += score[i+1][j].to_i
        end
      end
      
      print "Averaged score: "
      for i in 0..4
        printf "%s= %1.1f ", NAME[i], total1[i]/3.0
      end
      
      print "\n\n"
          
      # Average of each class
      
      for i in 0..2
        total2[i] = 0
      end
      
      for i in 0..2
        for j in 1..5
          total2[i] += score[j][i+1].to_i
        end
      end
      
      print "Averaged score of each class: "
      for i in 0..2
        printf "%s= %1.1f ", CLASS[i], total2[i]/5.0
      end
      
      print "\n"
      

      使用方法は,先ほどの成績データと組み合わせて,

      $ ruby average.rb record.txt

      のようにします.スクリプトの動作については,自分で考えてみましょう.

    • 要素の個数

      配列の要素の個数は以前に size メソッドにより調べることを説明し ました.上のような多重配列の要素の個数を見てみると良いでしょう.配列に操 作することの出来るメソッドに flatten (平らにする,という意味の 動詞) があります.配列に作用させてみて size を見ると動作が分か ります.

  5. 実習作業

    多重配列とループの組合わせの例について,自分でいろいろとスクリプトを変更 して試してみてください.

  6. 宿題

    授業の終りに宿題 (AクラスBクラス別々) について説明しますので,アナウンスに注意してください.


ページトップに移動

目次ページに戻る