Project1

标题: Reverse Polish notation calculator(Ruby) [打印本页]

作者: DeathKing    时间: 2011-7-31 08:46
标题: Reverse Polish notation calculator(Ruby)
本帖最后由 DeathKing 于 2011-7-31 14:33 编辑

标题

逆波兰表示法计算器(Ruby)



描述

逆波兰表示法是波兰数学家杨·武卡谢维奇(Jan Łukasiewicz)的研究成果。他使用后缀表示法来表示四则运算,不但不需要括号,而且只要知道运算符需要几个操作数就不会引起歧义。例如(后缀表示法即为逆波兰表示法):

前缀表示法:* + 1 2 - 4 5
中缀表示法:( 1 + 2 ) * ( 4 - 5)
后缀表示法:1 2 + 4 5 - *

请实现这样一个计算器,他能计算任何一个有效的逆波兰表示法表达式的值。对不合法的表达式,输出“ERROR”。



合法的表达式

合法的表达式满足下面的要求:




保证


范例输入(文件:rpn_input.txt)

01. 5 3 - 8 5 + /
02. 10 5 / 2 +
03. 8 * 7 + 5
04. ( 9 - 8 ) / 1



范例输出(文件:rpn_output.txt)

01. 0.15384615384615385
02. 4
03. ERROR
04. ERROR



文件

请按照 yourname_rpb.rb 的格式来提交文件,其中请将 yourname 替换为可作为您名称标识的有效英文字符。



我是被她们拉过来凑热闹的~~~


作者: DeathKing    时间: 2011-7-31 14:27
本帖最后由 DeathKing 于 2012-11-16 23:40 编辑

---
作者: DeathKing    时间: 2011-7-31 19:42
fux2 发表于 2011-7-31 12:17
待完善.

范例输入的前两个都是正确的逆波兰表达式,但是你的却说别人不正确 = =b
还有,规定的不正确直接输出 ERROR 在IO里面,自己乱输出是不算的。
作者: fux2    时间: 2011-7-31 20:23
本帖最后由 fux2 于 2011-7-31 23:49 编辑
DeathKing 发表于 2011-7-31 19:42
范例输入的前两个都是正确的逆波兰表达式,但是你的却说别人不正确 = =b
还有,规定的不正确直接输出 ERR ...


吾辈不才,还是放弃了.
备份:
  1. class String
  2.   define_method(:to_pol){Polish.new(self)}
  3. end

  4. class Polish
  5.   Calist = ["+","-","*","/"]
  6.   def initialize(ori)
  7.     @ori=ori
  8. #~     raise "It is not a standard Polish formula" unless ori[/^(\d+|PI|E)\s+(\d+|PI|E)\s*[\+\-\*\/](\s*(\d+|PI|E)\s*[\+\-\*\/])*$/]
  9.     raise "It is not a standard Polish formula" unless ori[/(^(\d+|PI|E)\s+(\d+|PI|E)\s*[\+\-\*\/](\s*(\d+|PI|E)\s*[\+\-\*\/])*$|(^(\d+|PI|E)\s+(\d+|PI|E)\s*[\+\-\*\/](\s*(\d+|PI|E)\s*[\+\-\*\/])*$){2}[\+\-\*\/])/]
  10.     i,t = [],""
  11.     ori.each_byte{|b|
  12.     if b.chr == " "
  13.       i<<t unless t==""
  14.       t=""
  15.     elsif Calist.include?(b.chr)
  16.       i<<t unless t==""
  17.       t=""
  18.       i.each_index do |q|
  19.         case i[q]
  20.         when /PI/
  21.           i[q] = Math::PI
  22.         when /E/
  23.           i[q] = Math::E
  24.         when /(\d+)/
  25.           i[q] = $1.to_s
  26.         end
  27.       end
  28.       i[0]=eval(i[0].to_s+b.chr+i[1].to_s)
  29.       i.delete_at 1
  30.     else
  31.       t=t+b.chr
  32.     end}
  33.     case t
  34.     when /PI/
  35.       t = Math::PI
  36.     when /E/
  37.       t = Math::E
  38.     end
  39.     @value=eval(i[0].to_s+t+i[1].to_s)
  40.   end
  41.   define_method(:value){@value}
  42.   define_method(:to_s){@ori}
  43. end
复制代码

作者: 六祈    时间: 2011-7-31 21:02
  1. module RPN
  2.   INPUT_FILEPATH = './rpn_input.txt'
  3.   OUTPUT_FILEPATH = './rpn_output.txt'

  4.   OPERATORS = ['+', '-', '*', '/']
  5.   CONST_NUMS= {
  6.     'PI' => Math::PI,
  7.     'E' => Math::E
  8.   }
  9.   
  10.   module_function
  11.   
  12.   def main
  13.     File.open(OUTPUT_FILEPATH,'w') do |f|
  14.       File.readlines(INPUT_FILEPATH).each do |line|
  15.         f.write(self.calculate_a_line(line).to_s + "\n")
  16.       end
  17.     end
  18.   end
  19.   
  20.   def calculate_a_line(line_str)
  21.     begin
  22.       re = []
  23.       eles = line_str.split(/ +/)
  24.       until eles.empty?
  25.         ele = eles.shift.chomp
  26.         if OPERATORS.include? ele
  27.           second_num = re.pop
  28.           first_num = re.pop
  29.           re << first_num.send(ele.to_sym,second_num)
  30.         elsif CONST_NUMS.include? ele
  31.           re << CONST_NUMS[ele]
  32.         elsif /^\d+$/ =~ ele
  33.           re << ele.to_f
  34.         else
  35.           raise 'DeathMore'
  36.         end
  37.       end
  38.       if re.size == 1
  39.         re.first
  40.       else
  41.         raise 'DeathMore'
  42.       end
  43.     rescue => e
  44.         'ERROR'
  45.     end
  46.   end

  47. end

  48. RPN.main
复制代码

作者: Margay    时间: 2012-1-29 02:15
  1. include Math
  2. numbers = []
  3. File.open("rpn_input.txt","r").read.split(/\s/).each {|i|i =~ /\d|(PI|E)/ ? numbers << i : numbers.size < 2 ? File.open("rpn_output.txt", "w") {|f| f.write "Error"} : numbers.push(eval(i.gsub!(/$/,numbers.pop.to_f.to_s).gsub!(/^/,numbers.pop.to_f.to_s)))}
  4. numbers.size == 1 ? File.open("rpn_output.txt", "w") {|f| f.write numbers.first} : File.open("rpn_output.txt", "w") {|f| f.write "Error"}
复制代码





欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1