Программа “Вычисление постфиксных выражений” на Ruby
-
23-08-2019 - |
Вопрос
Я попытался создать небольшой скрипт для оценки выражений после исправления в 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
- Я не знаю лучшего способа проверить, является ли символ в выражении целым числом, без использования этого грубого метода или регулярных выражений.Ребята, у вас есть какие-нибудь предложения?
- Есть ли способ абстрагироваться от этих случаев?Есть ли функция eval ("num1 ch num2") в Ruby?
Решение
если вы хотите проверить, является ли строка целым числом, 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
Другие советы
Я не знаю руби, поэтому не отвечаю на ваши вопросы.Однако здесь есть алгоритмическая проблема.Для сложения, умножения порядок операндов не имеет значения, но для вычитания и деления вы должны вычесть и разделить первый операнд на второй.Первый - это тот, что глубже в стеке.В результате вам следует поменять местами эти две строки:
num1 = my_stack.pop.to_i
num2 = my_stack.pop.to_i