Transcript Aula 2 - caversan.eng.br
Aplicações de Pilhas
Pilhas são fundamentais em diversas áreas da computação: ● ● ● ● Sistemas Operacionais Arquitetura de Computadores Compiladores Entre outros Uma aplicação clássica surge na necessidade de interpretar e executar expressões.
Análise de Expressões
Em determinadas aplicações, surge a necessidade de que o usuário informe fórmulas ou equações que o programa deve validar e calcular.
Como avaliar a expressão abaixo?
6 – ( ( A + ( B + C ) ) / ( ( D – 3 * E ) + ( F*A+10 ) )
E descartar expressões inválidas:
( D – E ) ) D + ( E ) A / D ( + E ( D + E) ) – (A + 2
Análise de Expressões
Conceitos:
•
profundidade do agrupamento
= total de parênteses de abertura encontrados cujos respectivos parênteses de fechamento ainda não foram encontrados.
•
diferença de parênteses
= total de parênteses de abertura subtraído do número de parênteses de fechamento, encontrados ao se percorrer a expressão matemática da extremidade esquerda até o ponto em análise.
Análise de Expressões
Primeiro passo: analisar se a expressão é ou não válida. Tentativa de solução:
1) No final da expressão a
diferença de parênteses
deve ser zero.
2) A
diferença de parênteses
em qualquer ponto da expressão é sempre positiva.
2 + ( ( A * C ) + ( ( D - E ) / ( B - 5 ) ) - 9 ) + 20 0 0 1 2 2 2 2 1 1 2 3 3 3 3 2 2 3 3 3 3 2 1 1 1 0 0 0 ( ( F * D ) + 5 1 2 2 2 2 1 1 1 F - D ) 0 0 0 -1 ) D / E ) + ) E -1 -1 -1 -1 -2 -2 -3 -3 ( B / A) ) ) - A + 2 * D ( ( 1 1 1 1 0 -1 -2 -2 -2 -2 -2 -2 -2 -1 0
Análise de Expressões
Problemas:
[ D – B ) { [ A / 2} ] { F – 8) ] {
Possível solução:
Utilização somente de parênteses (problemas futuros para calcular a expressão) Utilização de pilhas!
Análise de Expressões
Algoritmo usando pilhas (resultado na variável válido):
valido
VERDADEIRO construir Pilha S para cada caractere c da string entrada se (c =“(“ ou c =“[“ ou c =“{ “ ) então S.Empilhe (c) fim se se (c = “)” ou c =”]” ou c =“} “) então se (S.Vazia()) então valido
FALSO senão p = S.Desempilhe() se (p não é o respectivo iniciador de caracter c) então valido
FALSO fim se fim para fim se fim se se (não S.Vazia()) então valido
FALSO fim se
Análise de Expressões
Testar algoritmo na expressão:
2 + { [ F * 4 ] + [ ( A - B ) / ( C - 2 ) ] - 3 } + 4 [ D – B ) { [ A / 2} ] { F – 8) ] {
O problema de validar ou não expressões está resolvido. Mas e para calcular o seu valor, dadas as variáveis envolvidas?
- Primeiramente vamos analisar outras formas de representação de expressões, que podem facilitar o seu processamento pelo computador.
Avaliação de Expressões
Representação de Expressões: Infixa Operador está entre os operandos (A + B) Prefixa Operador precede os operandos Pósfixa Operador segue os operandos ( + AB ) ( A B + ) Forma prefixa: notação polonesa Forma pósfixa: notação polonesa reversa
Avaliação de Expressões
Regras básicas:
(a) Suponha a expressão : A+B*C (b) Coloque parênteses para reforçar a precedência: A + (B*C) (c) Converta a parte da multiplicação, obtendo : A+(BC*) (d) Suponha que D seja igual a BC*: A+D (e) Resultando em : AD+ (f) Realizando a devida substituição, ficamos com a forma final pósfixa igual à : ABC*+
Avaliação de Expressões
Exemplos:
Notação Infixa A - B * C Notação Pósfixa A B C * A * ( B - C) (A - B ) / (C + D) (A - B ) / (C + D)* E A^B * C – D + E / F / (G - H ) A B C - * A B - C D + / A B - C D + / E * AB ^C * D – EF / GH - / + ((A + B) * C – ( D – E )) ^ (F - G) AB + C * DE - - FG - ^
Avaliação de Expressões
Algoritmo para converter expressões:
Primeiramente, é preciso estabelecer prioridades entre os operadores (e para o parênteses):
método Prioridade (op) início caso op seja “(“ : retorno
“+”,”-“ : retorno
“*”,“/“ : retorno
“^” : retorno
fim fim caso 1 2 3 4
Avaliação de Expressões
Passos para converter a expressão:
Passo 1: • Inicie com uma pilha vazia; • Realize uma varredura na expressão
infixa
, copiando todos os operandos encontrados diretamente para a expressão de saída; Passo 2: Ao encontrar um operador: • Enquanto a pilha não estiver vazia e houver no seu topo um operador com prioridade maior ou igual ao encontrado, desempilhe o operador e copie o na saída; • Empilhe o operador encontrado; Passo 3: • Ao encontrar um parêntese de abertura, empilhe-o; Passo 4: • Ao encontrar um parêntese de fechamento, remova um símbolo da pilha e copie-o na saída. Repita esse passo até que seja desempilhado o parêntese de abertura correspondente.
Passo 5: • Ao final da varredura, esvazie a pilha, movendo os símbolos desempilhados para a saída. Pronto, conseguimos obter como saída a notação pósfixa para qualquer notação infixa entrada.
Avaliação de Expressões
posfixa
“” construir Pilha S para cada caractere c da string entrada caso c seja “A”..”Z”: posfixa
posfixa + c “+”,”-“, “*”,”/”,”^”: pr
Prioridade(c) enquanto ((não S.Vazia()) e (Prioridade(S.Topo())≥ pr)) faça posfixa
posfixa + S.Desempilhe() fim enquanto S.Empilhe (c) “(“ : S.Empilhe(c) “)” : x
S.Desempilhe() enquanto (x ≠ ”(“) faça posfixa
posfixa + x fim caso x
S.Desempilhe() fim enquanto fim para enquanto (não S.Vazia()) faça x
S.Desempilha() posfixa
posfixa + x fim enquanto
Cálculo de Expressões
Uma vez que se obtenha a expressão pósfixa, o cálculo é simples por um algoritmo.
Passo 1: • Inicie com uma pilha vazia; Passo 2: Varrer a expressão e, para cada símbolo encontrado na expressão, fazemos : • Se for operando, então empilhar seu valor; • Se for operador, então desempilhar os dois últimos valores. Em seguida efetuar a operação com eles. O resultado é empilhado novamente na pilha.
Passo 3: • No final do processo, o resultado da avaliação estará no topo da pilha.
Avaliação de Expressões
Algoritmo:
construir um vetor com as variáveis da expressão construir um vetor com os valores das variáveis construir Pilha S para cada caractere c da string posfixa se (c é “A”..”Z”) S.Empilhe(valor da variável c) senão y
S.Desempilhe() x fim para
S.Desempilhe() caso c seja: “+”: S.Empilhe(x+y) “-”: S.Empilhe(x-y) “*”: S.Empilhe(x*y) “/”: S.Empilhe(x/y) “^”: S.Empilhe(x^y) fim caso fim se resultado
S.Desempilhe()