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 FilaLista <char> CriarInfixa(ref string infixa)
        {
            FilaLista <char> seqInfixa = new FilaLista <char>();

            char letra = 'A';                                                                                                  //char que irá de A a Z para "substituir" os números

            valores = new double[26];                                                                                          //instanciação do vetor de valores
            string numero = "";                                                                                                //string que armazenará um valor lido, caracter por caracter

            for (int i = 0; i < txtVisor.Text.Length && !erro; i++)                                                            //percorre string do txtVisor, indexando-o como um vetor, até acabar as posições
            {
                char caracterAtual = (txtVisor.Text)[i];                                                                       //pega o caracter atual pelo index do for

                int num;                                                                                                       //variável apenas com fim de ser usada no tryParse
                if (int.TryParse(caracterAtual.ToString(), out num) || caracterAtual.Equals('.') || caracterAtual.Equals(',')) //se o valor for um número inteiro(como se está analisando apenas um caracter isolado, não se precisa usar double.TryParse)
                {                                                                                                              // ou se for um '.', ou seja, uma vírgula do double, ele faz parte de um número
                    if (caracterAtual.Equals('.'))
                    {
                        caracterAtual = ',';
                    }
                    numero += caracterAtual;                     //concatena caracter do número em formação
                }
                else if (numero != "")                           //se caracter lido não fizer mais parte de um número e a variável numero não for vazia
                {
                    valores[letra - 'A'] = double.Parse(numero); //armazena-se valor do número formado, convertendo-o para double
                    infixa += letra + "" + caracterAtual;        //concatena-se o número e o caracter lido na string infixa
                    seqInfixa.Enfileirar(letra);                 //enfileira letra referente a posição do número no vetor de valores
                    seqInfixa.Enfileirar(caracterAtual);         //enfileira caracter de operação
                    numero = "";                                 //esvazia string de número para que comece a formação de um novo caso haja
                    letra++;                                     //vai para a próxima letra
                }
                else //se o caracter lido for referente a uma operação mas não houver um número na variável numero (está vazia)
                {
                    if (caracterAtual.Equals('-') || caracterAtual.Equals('+')) //o caracter pode fazer parte do número, como "-1", mas daí o '+'/'-' tem que
                    {                                                           //estar logo no começo da sequência, ou estar precedido de '('
                        if (seqInfixa.EstaVazia() || seqInfixa.OFim().Equals('('))
                        {
                            numero += caracterAtual;
                        }
                        else
                        {
                            seqInfixa.Enfileirar(caracterAtual); //enfileira-se caracter atual
                            infixa += caracterAtual;             //concatena-se caracter atual em infixa
                        }
                    }
                    else
                    {
                        seqInfixa.Enfileirar(caracterAtual); //enfileira-se caracter atual
                        infixa += caracterAtual;             //concatena-se caracter atual em infixa
                    }
                }

                if (i + 1 == txtVisor.Text.Length && (numero != "") && !erro) // se o próximo index do vetor for o fim da operação mas o número não estiver vazio
                {
                    valores[letra - 'A'] = double.Parse(numero);              //armazena valor no vetor de valores
                    seqInfixa.Enfileirar(letra);                              //enfileira letra correspondente a valor
                    infixa += letra + "";                                     //concatena letra à sequencia infixa
                    numero  = "";                                             //esvazia número
                    letra++;                                                  //vai à próxima letra
                }
            }

            lblInfixa.Text = infixa; //exibe sequência infixa formada no lblInfixa

            return(seqInfixa);
        }
Exemple #3
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
            }
        }