1/14 パターン認識(1)



試験について


補足


前回の感想,質問より

Q.
maxrow(a,k)を
def maxrow(a,k)
max_i=k
for i in (k+1)..(a[0].length()-1)
if abs(a[max_i][k])<abs(a[k])
max_i=i
end
end
max_i
end
のように定義しましたが、gjp(a)を実行すると
NoMethodError: undefined method `[]' for nil:NilClass
from ./gjp.rb:7:in `maxrow'
from ./gjp.rb:6:in `each'
from ./gjp.rb:6:in `maxrow'
from ./gjp.rb:21:in `gjp'
from ./gjp.rb:20:in `each'
from ./gjp.rb:20:in `gjp'
というエラーメッセージが出てしまいます。意味がよく分からないので説明して頂けるとありがたいです。
A.
穴埋めプログラムでは,
  for i in (k+1)..(a.length()-1)
となっているが行が,
  for i in (k+1)..(a[0].length()-1)
に変わっていますね.a.length()はa[0].length()より1小さいので iが a[0].length()になった時には,a[ i ] は配列の範囲外を参照してしまいます.この時a[ i ]nilになり,a[ i ][ k ] の参照の際に,上記のエラーが発生するということになります.Ruby言語では配列の範囲外参照では,エラーにならずにnilを返す仕様になっているので,エラーの内容が見難いですね.
Q.
行の入れ替えによって情報落ち誤差を消すことができた
A.
教科書は「第2刷」をお使いでしょうか? 「第2刷」でこれを「情報落ち誤差」と記述しているのは正確でなく,第2刷 (2012-8-27): 正誤表で訂正されています.
Q.
def maxrow(a,k)
  #a[k]の絶対値が最大となるi>=kを探す
  a = k
  v = abs(a[k][k])
  l = a.length()
  for i in (k+1)..l
    if abs(a[k]) > v then
      v = abs(a[k])
      a = i
    end
  end
  return a
end
を実行すると、gjp(a)
NoMethodError: undefined method `length' for 0:Fixnum
from ./gjp.rb:9:in `maxrow'
from ./gjp.rb:23:in `gjp'
from ./gjp.rb:22:in `each'
from ./gjp.rb:22:in `gjp'
from (irb):20
from :0
と出ます。なぜでしょうか。
A.
maxrowの引数として配列aが出てくるのに,最大値を持つ時の添字(サンプルではmax_i)を表す変数にもaを使おうとしているためですね.a = k でaの値が整数に置き換わっているので,a.length()の行で問題のエラーを発生します.なお,整数aを2進数で表した時のk桁目が0か1かを a[k] で求めることができるようになっているので,a[k][k] ではエラーにならなかったようですね.

前回の課題について


投票システム

vote.rbをダウンロードして,ホームディレクトリに保存してください.ドックからターミナルを起動して,
ruby vote.rb 選択肢番号
のように使います.

今日の練習,投票


今日の課題