设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 2369|回复: 5
打印 上一主题 下一主题

[question] Reverse Polish notation calculator(Ruby)

[复制链接]
梦石
0
星屑
1185
在线时间
1564 小时
注册时间
2008-7-30
帖子
4418

贵宾

跳转到指定楼层
1
发表于 2011-7-31 08:46:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
本帖最后由 DeathKing 于 2011-7-31 14:33 编辑

标题

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



描述

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

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

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



合法的表达式

合法的表达式满足下面的要求:
  • 只能出现以下符号 {" ","/n","+","-","*","/"}∪R∪{PI,E} ,即只能包含空格符、换行符、四则运算符、有效的实数、两个常量标识符;
  • 符号{"+","-","*","/"} 都是二元操作符,需要两个操作数;
  • 常量{PI,E} 的取值参考对应的Math::PI,Math::E




保证
  • 输入文件中每行都是一个逆波兰表达式,每个操作数或操作符之间用空格符分隔;
  • 对于整数除法,结果是小数,则保留;
  • 输入文件文件名总是 rpn_input.txt ;
  • 输出文件文件名总是 rpn_output.txt ;



范例输入(文件: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 替换为可作为您名称标识的有效英文字符。



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


See FScript Here:https://github.com/DeathKing/fscript
潜心编写URG3中。
所有对URG3的疑问和勘误或者建议,请移步至发布页面。
欢迎萌妹纸催更
梦石
0
星屑
1185
在线时间
1564 小时
注册时间
2008-7-30
帖子
4418

贵宾

2
 楼主| 发表于 2011-7-31 14:27:20 | 只看该作者
本帖最后由 DeathKing 于 2012-11-16 23:40 编辑

---

点评

你这复杂得发囧= =  发表于 2011-7-31 16:17

See FScript Here:https://github.com/DeathKing/fscript
潜心编写URG3中。
所有对URG3的疑问和勘误或者建议,请移步至发布页面。
欢迎萌妹纸催更
回复 支持 反对

使用道具 举报

梦石
0
星屑
1185
在线时间
1564 小时
注册时间
2008-7-30
帖子
4418

贵宾

3
 楼主| 发表于 2011-7-31 19:42:12 | 只看该作者
fux2 发表于 2011-7-31 12:17
待完善.

范例输入的前两个都是正确的逆波兰表达式,但是你的却说别人不正确 = =b
还有,规定的不正确直接输出 ERROR 在IO里面,自己乱输出是不算的。

See FScript Here:https://github.com/DeathKing/fscript
潜心编写URG3中。
所有对URG3的疑问和勘误或者建议,请移步至发布页面。
欢迎萌妹纸催更
回复 支持 反对

使用道具 举报

老黄鸡

梦石
0
星屑
42397
在线时间
7602 小时
注册时间
2009-7-6
帖子
13506

开拓者贵宾

4
发表于 2011-7-31 20:23:32 | 只看该作者
本帖最后由 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
复制代码
RGDirect - DirectX驱动的RGSS,点我了解.
RM全系列成套系统定制请联系QQ1213237796
不接受对其他插件维护的委托
回复 支持 反对

使用道具 举报

旅之愚者

梦石
0
星屑
275
在线时间
812 小时
注册时间
2007-7-28
帖子
2148

贵宾

5
发表于 2011-7-31 21:02:50 | 只看该作者
  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
复制代码
回复 支持 反对

使用道具 举报

梦石
0
星屑
100
在线时间
145 小时
注册时间
2011-8-3
帖子
68
6
发表于 2012-1-29 02:15:28 | 只看该作者
  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"}
复制代码

点评

吾辈不才,还是放弃了.以上备份  发表于 2012-1-29 14:10
 
回复 支持 反对

使用道具 举报

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-11-22 17:35

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表