Exemple #1
0
        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
                }
            }
        }
Exemple #2
0
        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
            }
        }