private void ConverterParaPosfixa(FilaLista <char> seqInfixa, ref string posfixa) { char operadorComMaiorPrecedencia; PilhaLista <char> pilha = new PilhaLista <char>(); //pilha que será usada para empilhar operadores do { char simboloLido = seqInfixa.Retirar(); //simbolo lido é retirado da fila de sequencia infixa if (!(simboloLido <= 'Z' && simboloLido >= 'A')) //se o simbolo lido não estiver entre A e Z, ou seja, for um operador { if (pilha.EstaVazia()) //se a pilha estiver vazia, empilha-se simbolo lido { pilha.Empilhar(simboloLido); } else //se não estiver vazia { while (!pilha.EstaVazia() && DeveDesempilhar(pilha.OTopo(), simboloLido)) //enquanto a pilha não estiver vazia e deve desempilhar, ou seja, o topo da pilha tem precedencia sobre o simbolo lido { operadorComMaiorPrecedencia = pilha.Desempilhar(); //armazena-se operador com maior precedencia, tirando-o do topo if (operadorComMaiorPrecedencia != '(') //caso não seja '(', pois não se coloca parêntesis em sequências posfixas { seqPosfixa.Enfileirar(operadorComMaiorPrecedencia); //enfileira-se na seqPosfixa posfixa += operadorComMaiorPrecedencia; //concatena-se na string de posfixa } } if (simboloLido != ')') // empilha-se o simbolo lido, a menos que ele seja um ')' { pilha.Empilhar(simboloLido); } else { if (!pilha.EstaVazia() && pilha.OTopo() == '(') //se o simbolo lido for ')' e já foi feito o método acima sobre as precedencias, restará um parentesis aberto no topo da pilha, a menos que a sequência não esteja balanceada { operadorComMaiorPrecedencia = pilha.Desempilhar(); } else { erro = true; } } } } else // se for letra { seqPosfixa.Enfileirar(simboloLido); //enfileira-se letra na sequência posfixa += simboloLido; //concatena-se a letra na string posfixa } }while (!seqInfixa.EstaVazia() && !erro); //enquando não estiver vazia e não houver nenhum erro, continua-se a expressão while (!pilha.EstaVazia() && !erro) // se a fila de sequência ja estiver acabado mas houver operandos na pilha e não tiver dado erro { operadorComMaiorPrecedencia = pilha.Desempilhar(); //desempilha-se elemento da pilha if (operadorComMaiorPrecedencia != '(') //se não for '(' { seqPosfixa.Enfileirar(operadorComMaiorPrecedencia); //enfileira elemento posfixa += operadorComMaiorPrecedencia; //concatena à string posfixa } } }
private void Calcular() { PilhaLista <double> pilhaValores = new PilhaLista <double>(); //pilha que armazena valores da expressão do { char simbolo = seqPosfixa.Retirar(); //retira-se um simbolo da sequência posfixa if (simbolo >= 'A' && simbolo <= 'Z') //se o símbolo for uma letra { double valor = valores[simbolo - 'A']; //recupera valor referente à letra indexando o vetor valores pilhaValores.Empilhar(valor); //empilha valor recebido } else // se for operador { double valor = 0; double operando2 = 0; double operando1 = 0; if (pilhaValores.Tamanho() < 2) { erro = true; //não há elementos suficientes para desempilhar os operandos, ou seja, o usuário digitou operadores 'sobrando' txtResultado.Text = "Erro: operadores a mais"; } else { operando2 = pilhaValores.Desempilhar(); //o segundo operando é referente ao topo da pilha, e é desempilhado operando1 = pilhaValores.Desempilhar(); //desempilha-se primeiro operando } switch (simbolo) //switch para realizar diferentes operações dependendo do operador { case '*': valor = operando1 * operando2; break; case '/': if (operando2 == 0) // na divisão, não se pode ter divisor 0 { txtResultado.Text = "Erro: Divisão por 0"; erro = true; } else { valor = operando1 / operando2; } break; case '^': valor = Math.Pow(operando1, operando2); break; case '+': valor = operando1 + operando2; break; case '-': valor = operando1 - operando2; break; } pilhaValores.Empilhar(valor); //empilha-se valor da sub-expressão realizada } }while (!seqPosfixa.EstaVazia() && !erro); // continua caso não tenha acabado a sequencia e não tenha havido erro if (!erro) //se não tiver dado erro { double resultado = pilhaValores.Desempilhar(); //como os resultados das sub-expressões vão sendo armazenados na pilha, ao final restará o resultado txtResultado.Text = resultado.ToString(); //exibe resultado } }