Оценка программы Postfix Expressions в Ruby

Я попытался написать небольшой скрипт для оценки постфиксных выражений в 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")?

person unj2    schedule 19.05.2009    source источник


Ответы (2)


если вы хотите проверить, является ли строка целым числом, Integer() — это элегантный способ сделать это, потому что он гарантирует, что ваше определение целого числа совпадает с определением ruby. если вы предпочитаете не использовать это, потому что оно генерирует исключение, регулярные выражения прекрасно работают - зачем их избегать? также обратите внимание, что в целочисленном случае вы можете просто поместить y в свой стек, а не ch, и вам не нужны вызовы to_i при извлечении. что касается другого вопроса, у ruby ​​действительно есть eval.

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  
person Martin DeMello    schedule 20.05.2009

Я не знаю руби, поэтому я не отвечаю на ваши вопросы. Однако здесь есть алгоритмическая проблема. Для сложения, умножения порядок операндов не имеет значения, но для вычитания и деления вы должны вычесть и разделить первый операнд на второй. Первый находится глубже в стеке. В результате вы должны поменять местами эти две строки:

num1 = my_stack.pop.to_i
num2 = my_stack.pop.to_i
person mmx    schedule 19.05.2009