Algoritmo de Shunting-Yard
Um algoritmo que transforma expressões matemáticas infixas em posfixas.
Motivação
Expressão infixa
Expressão posfixa
A*2
A2*
(A*2+c-d)/2
A2*c+d-2/
(2*4/a^b)/(2*c)
24*ab^/2c*/
A tarefa de transformar expressões matemáticas infixas para posfixas é bastante útil por dar um formato mais fácil ao computador para calcular as expressões da forma como escrevemos, removendo algumas das ambiguidades que suscetivelmente escrevemos. Repare que na forma posfixa sempre temos primeiro os operandos e depois o operador, fazendo com que o cálculo seja muito mais simples, num processo onde se vai acumulando os operandos numa pilha e toda vez que ler um operador, retirar os dois operandos que estão mais no topo, fazer a conta e retornar o resultado para o topo da pilha, assim sucessivamente até que se acabe a expressão e o resultado esteja no topo da pilha restante.
Para a explicação deste algoritmo, vamos considerar quatro tipos diferentes de símbolos possíveis na nossa expressão matemática:
Operandos: representados na entrada como caracteres alfanuméricos
Operadores: representados na entrada como os caracteres
+
,-
,*
,/
e^
Parênteses aberto: representando o começo de uma subexpressão
Parênteses fechado: representando o final de uma subespressão
Também vamos precisar considerar a precedência dos operadores, ou seja, a ordem em que precisamos fazer as contas. A fim de permanecer em caráter computacional, vamos entender precedência como números, onde um número maior significa maior precedência.
Operador
Precedência
+
1
-
1
*
2
/
2
^
3
Para traduzirmos corretamente a expressão infixa para posfixa, o algoritmo utiliza uma pilha para guardar os operadores e os parênteses à medida que formos lendo cada um deles. Com isso, vamos lendo a expressão um caractere por vez, tomando medidas diferentes dependendo de qual caractere estamos lendo no momento:
Se o caractere é um operando, escrever tal caractere direto na resposta
Se o caractere é um parênteses aberto, colocar um parênteses aberto na pilha
Se o caractere é um parênteses fechado, ir tirando operadores da pilha, escrevendo-os na resposta, até encontrarmos um parênteses aberto na pilha, caso em que vamos retirá-lo da pilha, mas não vamos escrevê-lo na resposta
Se o caractere é um operador, ir tirando operadores da pilha, escrevendo-os na resposta, até uma dessas três possibilidades acontecer. Quando algo abaixo acontecer, coloque o operador na pilha e passe para o próximo caractere.
A pilha estar vazia
Encontrarmos um parênteses aberto
Encontrarmos um operador com precedência menor do que a do operador que lemos naquele momento
Seria inteligente aqui separarmos o caso em que lemos
^
para ir direto colocar na pilha, já que qualquer operador que encontrássemos na pilha teria precedência menor que^
É possível com esse mesmo algoritmo detectar erros na expressão infixa caso isso seja necessário. Repare que dependendo que como a expressão é escrita, podemos nos deparar com alguns casos indesejáveis:
Podemos ter dois ou mais operandos sucessivos.
Podemos ter parênteses sobrando ou faltando, caso em que teremos ou parênteses sobrando na pilha ou final da operação ou o parêntese fechado sendo incapaz de desempilhar um parêntese aberto.
Nestes casos, é possível acrescentar facilmente algumas verificações para evitar que estes casos ocorram, se seguirmos usando este algoritmo.
Implementação
Para as implementações de pilha usadas neste algoritmo, confira nossa página de pilhas.
Problemas
1077 - Infixa para PosfixaLast updated