Avaliação de expressões Prof: Sérgio Souza Costa
Avaliação de expressões Como efetuar o cálculo de uma expressão em um computador? A / B * (D + C)
Avaliação de expressões - Notações
Avaliação de expressões - Notações Infixa: A + (B*C) / D
Avaliação de expressões - Notações Infixa: A + (B*C) / D Posfixa (polonesa reversa): A B C * + D /
Avaliação de expressões - Notações Infixa: A + (B*C) / D Posfixa (polonesa reversa): A B C * + D / Préfixa (polonesa): + A / * B C D
Notação Infixa Operadores entre operandos. 4 + 6 * 8
Notação Infixa Operadores entre operandos. 4 + 6 * 8 Como decidir quais operadores são avaliados primeiros?
Notação Infixa Operadores entre operandos. 4 + 6 * 8 Como decidir quais operadores são avaliados primeiros?
Notação Infixa - Avaliação Operadores entre operandos. 4 + 6 * 8 Como decidir quais operadores são avaliados primeiros? Abordagem usual é usar as mesmas regras da matemática. Caso a prioridade seja a mesma, avalia-se da esquerda para direita Parenteses tem precedência sobre todos operadores.
Notação Infixa - Precedência Quando usamos a notação infixa é importante sabermos a ordem de precedência dos operadores, por exemplo, abaixo temos uma lista ordenada dos operadores por ordem de precedência. () [] ->! ~ ++ -- * & (tipo) sizeof() * / % + - >> << < <= >= > ==!= & ^ &&? () : () = += -= *=
Notação Polonesa É fácil observar que devido a estas regras, o algoritmo para avaliar expressões na notação infixa não é muito trivial. O matemático polonês Jan Łukasiewicz criou uma notação em torno de 1920 que elimina a necessidade de regras. Ficou sendo conhecida como notação polonesa. Não é muito usado na matemática convencional, mas muito usado nas ciências da computação.
Notação Polonesa e Polonesa Reversa Notação Polonesa ou Prefixa, os operadores aparecem antes dos operandos. + A B Notação Polonesa reversa ou Pósfixa, os operadores aparecem logo após os operandos. A B +
Algoritmos
Notação Posfixa A avaliação de expressões nesta notação é a mais simples. Percorrendo uma expressão da esquerda para direita, sabemos que ele deve operar os dois últimos valores encontrados.
Notação posfixa Considerem a seguinte expressão 73+5*. Expressão Elemento Ação Pilha 73+5* P:[] 3+5* 7 Empilhar P:[7] +5* 3 Empilhar P:[3,7] 5* + Desempilha 3 Desempilha 7 Empilha 3+7 P:[7] P:[] P:[10] * 5 Empilhar P:[5,10] * Desempilha 5 Desempilha 10 Empilha 5*10 P:[10] P:[] P:[50] Se a pilha tiver mais de um elemento, erro, caso contrário retorna o único valor da pilha.
Atividade Simulem a avaliação da seguinte expressão 3 5 2 * * 6 /
Atividade Escrevam o algoritmo que avalia uma expressão na notação posfixa. Considere uma expressão simples, somente o operador + e cada valor contem apenas um caracter de 0 a 9. Considerem tambem que a expressão é sempre válida. Por exemplo: Notação posfixa 12+ Notação prefixa 1+2
Solução Uma versão simplificada para a avaliação de expressão posfixa: int avalia_expressao (char s[]) { int t; Stack p = stack_init(); while (*s) { switch (*s) { case '+': push (&p, pop (&p) + pop (&p)); break; default: push (&p, *s - '0' ) ; } s++; } return pop (&p); }
Notação infixa para posfixa Dada uma expressão na notação infixa, podemo convertê-la para posfixa.
Notação infixa para posfixa Dada uma expressão na notação infixa, podemo convertê-la para posfixa. Versão simplificada: Cada valor também tem apenas um caracter. Ela é sempre válida. E não existe prioridade de operadores, todas operações estaram dentro de parenteses. Por exemplo: 4 + 5 + 6 equivale ((4 + 5) + 6 )
Notação infixa para posfixa Dado uma expressão totalmente parentetizada: Algoritmo: Percorrer a expressão da esquerda para direita, e para cada caracter faça: Parenteses de abertura ignorar Se for operando, copiar para expressão de saida Se for operador, aguardar na pilha Se for fechamento de abertura, copiar o ultimo operador acessado.
Notação infixa para posfixa Para a expressão ( (3 + 5) + 9 ): Simbolo Ação Pilha Saída ( ignora P:[] ( ignora P:[] 3 copia P:[] 3 + aguarda P:[+] 3 5 copia P:[+] 3 5 ) desempilha + copia p:[] p:[] 3 5 3 5 + + aguarda P:[+] 3 5 + 9 copia P:[+] 3 5 + 9 ) desempilha + copia p:[] 3 5 + 9 3 5 + 9 +
Atividade Simulem a conversão da seguinte expressão para forma posfixa: (5 * (8 + 2))
Atividade Codifiquem o algoritmo que realiza a conversão entre infixa e posfixa.
Solução Uma versão simplificada: char* infixtoposfix (char s[]) { char* iter; char* saida = malloc (50*sizeof (char)); iter = saida; Stack p = stack_init(); while (*s) { switch (*s) { case '(': break; case '+': push(&p, *s); break; case ')': *(iter++) = pop (&p); break; default: *(iter++) = *s; break; } s++; } *iter = '\0'; } return saida;
Atividades Testem e concluem os algoritmos para avaliação de expressão posfixa e para conversão entre as notações infixa e posfixa. Para a conversão, considerem as prioridades entre os operadores. Próxima aula será no laboratório.