Ruby中的“评估Postfix表达式”程序

时间:2009-05-19 22:11:28

标签: ruby postfix-notation

我尝试制作一个小脚本来评估Ruby中的修复后表达式。

def evaluate_post(expression)

    my_stack = Stack.new

    expression.each_char do |ch|        
    begin    
        # Get individual characters and try to convert it to integer
        y = Integer(ch)

        # If its an integer push it to the stack
        my_stack.push(ch)

    rescue    
        # If its not a number then it must be an operation
        # Pop the last two numbers
        num2 = my_stack.pop.to_i            
        num1 = my_stack.pop.to_i


        case ch
        when "+"   
            answer = num1 + num2        
        when "*"       
            answer = num1* num2    
        when "-"        
            answer = num1- num2     
        when "/"        
            answer = num1/ num2    
        end   

        # If the operation was other than + - * / then answer is nil
        if answer== nil
        my_stack.push(num2)
        my_stack.push(num1)
        else
        my_stack.push(answer)
        answer = nil
        end
    end
    end

    return my_stack.pop
end
  1. 我不知道更好的方法来检查表达式中的字符是否为整数而不使用这种粗略的方法或正则表达式。你们有什么建议吗?
  2. 有没有办法抽象案件。 Ruby中是否有eval(“num1 ch num2”)函数?

2 个答案:

答案 0 :(得分:2)

我不知道红宝石,所以我不回答你的问题。但是那里有一个算法问题。对于add,乘以操作数的顺序无关紧要,但对于减法和除法,应该减去第一个操作数并除以第二个操作数。第一个是堆叠更深的一个。因此,您应该交换这两行:

num1 = my_stack.pop.to_i
num2 = my_stack.pop.to_i

答案 1 :(得分:2)

如果你想检查字符串是否是一个整数,Integer()是一种优雅的方法,因为它确保你的整数定义与ruby相匹配。如果您不想使用它,因为它会抛出异常,正则表达式可以正常工作 - 为什么要避免使用它们?另外,请注意,在整数的情况下,您可以简单地将y推入堆栈,而不是ch,并且在弹出时不需要to_i调用。至于另一个问题,红宝石确实有一个评估。

y = Integer(ch) rescue nil   
if y  
  stack.push(y)  
else  
  num2, num1 = stack.pop(2)  
  a = eval "#{num2} #{ch} #{num1}" # see mehrdad's comment for why not num1 ch num2  
  stack.push(a)  
end