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 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); }
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 } }