Hatena::Grouprubyist

krystal: プログラミング超初心者(文系)

2008-11-27 (Thu)たのしいRuby練習問題

P230 - "七千百二十三"といった、漢数字による数の表現を「7123」のような数値に変換するメソッドkan2numを定義してみよう

20:49

def kan2num(kan)
  before_ten = kan.split(//s)[(kan.index("")/2 - 1)]

=begin
修正前のコードはこれ:
before_ten = kan.split(//s)[(kan.index("十") - 2)]
before_hundred = kan.split(//s)[(kan.index("百") - 2)]
before_thousand = kan.split(//s)[(kan.index("千") - 2)]

で、can't convert nil to string というエラーが出た
そこで p デバッグ!!

p kan.index("十")                         #=> これは正しかった
p kan.index("十") - 20                    #=> これも大丈夫だった
p kan.split(//s)[(kan.index("十") - 2)]   #=> nil
p kan.split(//s)                          #=> ここでkanを配列にしてしまってることがわかった。だからindexの数値にズレが生じた。
=end

  before_hundred = kan.split(//s)[(kan.index("")/2 - 1)]
  before_thousand = kan.split(//s)[(kan.index("")/2 - 1)]
  one_to_nine = "一二三四五六七八九"
  
  kan.split(//s).map {|change|
    case change
    when ""
      print 1
    when ""
      print 2
    when ""
      print 3
    when ""
      print 4
    when ""
      print 5
    when ""
      print 6
    when ""
      print 7
    when ""
      print 8
    when ""
      print 9
    when ""
      if one_to_nine.include?(before_ten) == false or kan.split(//s)[0] == ""
        print 1
      end
    when ""
      if one_to_nine.include?(before_hundred) == false or kan.split(//s)[0] == ""
        print 1
      end
    when ""
      if one_to_nine.include?(before_thousand) == false or kan.split(//s)[0] == ""
        print 1
      end
    end
  }

end
kan2num("三千百六十八")   #=> 3168
puts
kan2num("千四百七十一")   #=> 1471
puts
kan2num("九千五百十二")   #=> 9512

やはりエラーが出ると慌ててしまう。

追記:「0」のことを考えてなかった!"六千"とかは正しく表示されないね。。。


CD-ROM による正解はこれ

  • まだHashクラスの勉強に入ってないからHashを使ってないかも
  • だけど正規表現クラスの勉強にも入ってないのに、$1とか使ってる
  • これはよい正解なのか
def kan2num(string)
  digit4 = '0'
  digit3 = '0'
  digit2 = '0'
  digit1 = '0'
  
  nstring = string.dup
  nstring.gsub!(//,'1')
  nstring.gsub!(//,'2')
  nstring.gsub!(//,'3')
  nstring.gsub!(//,'4')
  nstring.gsub!(//,'5')
  nstring.gsub!(//,'6')
  nstring.gsub!(//,'7')
  nstring.gsub!(//,'8')
  nstring.gsub!(//,'9')

  if nstring =~ /((\d)?千)?((\d)?百)?((\d)?十)?(\d)?$/
    if $1
      digit4 = $2 || '1'
    end
    if $3
      digit3 = $4 || '1'
    end
    if $5
      digit2 = $6 || '1'
    end
    digit1 = $7 || '0'
  end
  return (digit4+digit3+digit2+digit1).to_i
end

if __FILE__ == $0
  print kan2num('七千百二十三'),"\n"
end