せっかく逆ポーランド記法に変換できたので簡単な電卓にまとめた

中置記法から後置記法(逆ポーランド記法)への変換の続き。
中置記法〜にも書いてあるけど、中置の +, -, *, / を実装。前置の - は実装してない。
オペランドは整数のみ。割り算になると Float に変換。

実行例

が入力、黒が出力。

(1+2)*5/4
3.75
1+2*5/4
3.5

ソース

メソッド ifn2pfn は、中置記法〜と同じ。

# Calculator 

# infix notation to postfix notation
# refer to http://www.gg.e-mansion.com/~kkatoh/program/novel2/novel208.html
def ifn2pfn ifn
  i = 0
  stack = []
  pfn = ""
  while i < ifn.size
    c = ifn[i].chr
    if c == " "
      i += 1
    elsif c =~ /[0-9]/
      c << ifn[i] while ifn[i+=1] =~ /[0-9]/
      pfn << c + " "
    elsif c == ")"
      until (s = stack.pop) == "("
        pfn << s + " "
      end
      i += 1
    elsif c == "("
      stack.push c
      i += 1
    else
      if stack.empty?
        stack.push c
      else
        if c =~ /[-\+]/
          until stack.empty?
            s = stack.pop
            if s =~ /[\*\/]/
              pfn << s + " "
            else
              stack.push s
              break
            end
          end
        end
        stack.push c
      end
      i += 1
    end
  end
  until stack.empty?
    pfn << stack.pop + " "
  end
  pfn.chop
end

def calc_rpn rpn
  stack = []
  o = rpn.split " "
  o.each do |e|
    case e
    when "+"
      stack.push(stack.pop + stack.pop)
    when "-"
      stack.push(stack.pop - stack.pop)
    when "*"
      stack.push(stack.pop * stack.pop)
    when "/"
      a = stack.pop.to_f
      b = stack.pop.to_f
      stack.push(b / a)
    else
      stack.push(Integer(e))
    end
  end
  stack[0]
end

puts(calc_rpn(ifn2pfn(readline.chomp))) while true