Aula 2 - caversan.eng.br

Download Report

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()