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
  1. 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?
  2. Existe uma maneira de abstrair os casos. Existe uma função em Ruby eval ( "num1 ch num2")?
Foi útil?

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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top