“Avaliando Postfix Expressions” Programa em Ruby
-
23-08-2019 - |
Pergunta
Eu tentei fazer um pequeno script para avaliar expressões pós-fix em 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
- Eu não sei a melhor maneira de verificar se o personagem na expressão é um inteiro sem usar este método bruto ou expressões regulares. Vocês têm alguma sugestão?
- Existe uma maneira de abstrair os casos. Existe uma função em Ruby eval ( "num1 ch num2")?
Solução
Se você quiser verificar se uma string é um número inteiro, Integer () é uma maneira elegante de fazer isso, porque ele garante a sua definição de um inteiro corresponde rubi do. Se você preferir não usar isso, porque ele lança uma exceção, expressões regulares funcionar muito bem - por que evitá-los? Também, nota que, no caso inteiro, você pode simplesmente empurrar y na sua pilha, não pc, e não precisa as chamadas to_i quando popping. Quanto à outra questão, rubi, de fato, ter um 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
Outras dicas
Eu não sei rubi então eu não responder às suas perguntas. Há um problema algorítmico lá, no entanto. Para adicionar, multiplicar a ordem de operandos não importa, mas para a subtração e divisão, você deve subtrair e dividir o primeiro operando pelo segundo. O primeiro é o mais profundo na pilha. Como resultado, você deve trocar estas duas linhas:
num1 = my_stack.pop.to_i
num2 = my_stack.pop.to_i