Программа "Оценка выражений Postfix" в Ruby - PullRequest
0 голосов
/ 20 мая 2009

Я попытался создать небольшой скрипт для оценки выражений после исправления в 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. Я не знаю лучшего способа проверить, является ли символ в выражении Integer без использования этого грубого метода или регулярных выражений. Ребята, у вас есть предложения?
  2. Есть ли способ абстрагировать дела? Есть ли в Ruby функция eval ("num1 ch num2")?

Ответы [ 2 ]

2 голосов
/ 20 мая 2009

Если вы хотите проверить, является ли строка целым числом, Integer () - это элегантный способ сделать это, потому что он гарантирует, что ваше определение целого числа соответствует ruby. если вы не хотите использовать это, потому что оно вызывает исключение, регулярные выражения работают хорошо - зачем их избегать? Также обратите внимание, что в целочисленном случае вы можете просто вставить y в свой стек, а не ch, и не вызывать вызовы to_i при извлечении. Что касается другого вопроса, рубин действительно имеет 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  
2 голосов
/ 20 мая 2009

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

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