Duvida com Algoritmo!

Olá estou desenvolvendo uma calculadora que recebe como parâmetro de entrada uma expressão normal como essa 2+3+5+7*(8/2), e tem que me retornar ela em notação polonesa ,porem estou com algumas dificuldades na hora de definir a prioridade dos operadores e com os parenteses se alguem puder me dar uma dica do que posso melhorar agradeço .

Segue Parte do Código que avalia a Expressão (lembrando que sou obrigado a usar Pilha e Fila ).

[code]public class CalculadoraPolonesa {

private Fila filaAuxiliar;
private Pilha pilha;

public CalculadoraPolonesa() {
    filaAuxiliar = new Fila();
    pilha = new Pilha();
}

public void avaliaExpressao(String entrada) throws EmptyStackException {
    for (int i = 0; i < entrada.length(); i++) {
        char c = entrada.charAt(i);
        if (!eEspaco(c)) {
            String aux = "";
            if (eNumerico(c)) {
                while (eNumerico(c)) {
                    aux += c;
                    c = entrada.charAt(++i);
                }
                //converte a String para um inteiro

                filaAuxiliar.inserir(Integer.parseInt(aux));
            }
            if (c == '(') {
                pilha.push(c);
            } else if (c == ')') {
                while (true) {
                    Object x = pilha.pop();
                    if (x.equals('(')) {
                        break;
                    }
                    filaAuxiliar.inserir(x);
                    break;
                }
            } else if (eOperador(c)) {
                Object operadorTopoPilha = null;
                if (pilha.isEmpty()) {
                    pilha.push(c);
                } else {                    	
                    operadorTopoPilha = pilha.pop();
                    while (true) {
                        if (testaPrioridade(c, operadorTopoPilha.toString().charAt(0)) || pilha.isEmpty()) {
                            pilha.push(c);
                            break;
                        } else {
                            filaAuxiliar.inserir(pilha.pop());
                            i++;
                        }
                    }
                }
            }
        }

    }
    while (!pilha.isEmpty()) {
        filaAuxiliar.inserir(pilha.pop());

    }
}

private boolean eOperador(char c) {
    return (c == '+' || c == '-' || c == '*' || c == '/');
}

private boolean eNumerico(char c) {
    return (c >= '0' && c <= '9');
}

private boolean eEspaco(char c) {
    return ((int) c) == ' ';
}

private boolean testaPrioridade(char p2, char p1) {
    return ((p2 == '*' || p2 == '/') && (p1 == '+' || p1 == '-'));
}

public String imprimeExpressaoPolonesa() {
    return filaAuxiliar.imprimir();
}

}[/code]

Olha é um assunto um pouco complexo e como pude ver que ninguém ainda respondeu
vou te passar uns links para você ver se resolve seu problema.

http://www.youtube.com/watch?v=XVYH8MEaQ1U (calculadora meio avançada)

http://www.youtube.com/watch?v=ZtvNX6GwmFk(calculadora científica)

http://www.youtube.com/results?search_query=scientific+calculator+java

http://www.filecrop.com/calculadora-cientifica-para-celular-en-java-.jar.html (Esse link tem vários jar disponíveis de calculadoras prontas em java)

Bom com esses links acho que dá para ver algumas formas de fazer.

Espero ter ajudado um pouco.
Abraço.

Cara, você precisa mesmo implementar isso? E se precisar, tem que ser em java?

Isso sai fácil usando arvore, mas fazer arvore em java…

Eu aconselho a fazer pseudocódigo mesmo, ou implementar em C ou Pascal, que ai você brinca com os ponteiros e todas essas palhaçadas. Mas aviso logo, é muito trabalhoso brincar disso…

[quote=GabrielMantini]Cara, você precisa mesmo implementar isso? E se precisar, tem que ser em java?

Isso sai fácil usando arvore, mas fazer arvore em java…

Eu aconselho a fazer pseudocódigo mesmo, ou implementar em C ou Pascal, que ai você brinca com os ponteiros e todas essas palhaçadas. Mas aviso logo, é muito trabalhoso brincar disso…[/quote]

Por isso que não quis postar nada a mais que vídeos e sites com exemplos já feitos.
Vai saber a trabalheira que isso vai dar, sem contar que já pode existir uma pronta
para consulta didática.

Cara, eu fiz uma versão simplificada do algoritmo de Shunting-Yard.

Funciona bem, se quiser consultar, está no github. É só clicar aqui.

É, eu to falando que é trabalhoso pq tentei fazer o mesmo, que o nosso amigo aqui, período passado na faculdade. Desisti de fazer em java e implementei em pascal, mas jamais faria aquilo de novo, perdi muito tempo pra acertar, sem contar que é um saco trabalhar com uma expressão toda em string e converter os valores, ainda mais no caso dos operadores.
Pq, pelo menos no meu caso, eu ainda tinha que calcular o valor de todas as formas(parentizada, polonesa e polonesa reversa).

Se conseguir separar bem, até que é simples implementar seguindo o pseudo-código do wikipedia.

Se alguém reparar no exemplo que eu passei, vai ver que boa parte da lógica foi colocada no enum Operator, onde criei métodos pra facilitar a minha vida

lordabel, tente achar algum tempinho para estudar sobre design patterns. Vc consegue fazer esse algoritmo ficar show de bola se estudar padrões.
Não perca tempo fazendo tudo estruturado não…

Obrigado Galera pela as Resposta mas , ainda estou na faculdade e era obrigatório o uso de Pilha e Fila ,e eu consegui fazer, fico bem legal irei postar aqui o resultado para que vocês digam o que acham do código que eu fiz.
Segue o codigo terminado é funcionando .

[code]
package CalculadoraPolonesa;

public class Calculadora {

private Fila fila;
private Pilha pilha;

public Calculadora() {
    fila = new Fila();
    pilha = new Pilha();
}

/**
 * Testa a prioridade dos Operadores.
 *
 * @param Object object
 * @return inteiro
 */
private int ObterPrioridade(Object object) {
    int retorno = 0;
    String pri1 = "+-";
    String pri2 = "*/";
    if ("(".equals(object.toString())) {
        retorno = 1;
    } else if (pri1.indexOf(object.toString()) >= 0) {
        retorno = 2;
    } else if (pri2.indexOf(object.toString()) >= 0) {
        retorno = 3;
    } else if ("^".equals(object.toString())) {
        retorno = 4;
    }
    return retorno;
}

/**
 * Testa se é um Numero.
 *
 * @param String digit
 * @return True or False
 */
public static boolean isADigit(String digit) {

    return digit.matches("^[0-9]{1,3}$");

}

/**
 * Testa se é Um Operador.
 *
 * @param String ch
 * @return True or False
 */
private boolean operador(String ch) {

    return ch.matches("[+|\\-|*|/|^]");

}

/**
 * Converte a expressao de forma Infixa para Poxfixa
 *
 * @param String expInfixa
 */
private void ConverterPosFixa(String expInfixa) {
    String item;
    expInfixa.trim();
    String[] caracter = expInfixa.split("");
    int prioridade = 0;

    /*
     * Varre todos os elementos da expressao de entrada e, para cada
     * elemento, verifica se e operador ou parenteses adiciona a pilha. Se
     * for operando adicona a fila.
     */
    for (int i = 1; i <= expInfixa.length(); i++) {


        if ((isADigit(caracter[i])) && (!caracter[i].matches("[(|)]"))) {

            fila.enqueue(caracter[i]);

        } else if (operador(caracter[i])) {
            prioridade = ObterPrioridade(caracter[i]);
            while ((pilha.getLength() != 0) && (ObterPrioridade((pilha.peek())) >= prioridade)) {

                fila.enqueue(pilha.pop().toString());

            }

            // Insere o objeto no topo da pilha
            pilha.push(caracter[i]);
        } else if ("(".equals(caracter[i])) {
            // Insere o objeto no topo da pilha
            pilha.push(caracter[i]);
        } else if (")".equals(caracter[i])) {
            item = pilha.pop().toString();

            fila.enqueue(item);

            while (!item.equals("(") && !pilha.isEmpty()) {
            // Recupera e remove o objeto do topo da pilha
                item = pilha.pop().toString();

            }
        }
    }
    /**
     * Desimpilha todos Objetos e insere na Fila.
     */
    while (!pilha.isEmpty()) {

        fila.enqueue(pilha.pop().toString());

    }

}

/**
 * Avalia uma expressao na forma infixa, mas antes de avaliar, converte-a
 * para forma posfixa.
 *
 * @param String expInfixa
 * @return resultado da expressao
 * @throws Exception
 */
public String AvaliarExpressao(String expInfixa) throws Exception {

    ConverterPosFixa(expInfixa);

    while (!fila.vazia()) {


        if (isADigit(fila.topoFila().toString())) {
            pilha.push(fila.equeue().toString());
        } else {
            if (operador(fila.topoFila().toString())) {
                double y = Double.parseDouble(pilha.pop().toString());
                double x = Double.parseDouble(pilha.pop().toString());
                switch (fila.equeue().toString()) {
                    case "+":
                        pilha.push((x + y));
                        break;
                    case "-":
                        pilha.push((x - y));
                        break;
                    case "*":
                        pilha.push((x * y));
                        break;
                    case "/":
                        pilha.push((x / y));
                        break;
                    case "^":
                        pilha.push((Math.pow(x, y)));
                        break;
                }
            }
        }
    }
    return pilha.pop().toString();
}

}[/code]

Opa, que bom que conseguiu resolver :slight_smile: Mas segue umas dicas:

Para melhorar sua nota:

  • Nunca comece o nome de um método com letra em maiúsculo, é convencional começar com o nome minúsculo, e a cada troca de palavra a primeira letra é maiúscula. Ex: “openConnection”, “getPartialContent”. (Se eu fosse o professor eu me atentaria a isso)

Se tiver interesse em seguir carreira como programador:

  • Divida melhor seu código, cada classe deve ter uma única responsabilidade (SRP), deve ser coesa.
  • Pesquise por padrões para deixar seu código mais limpo e organizado, no caso o padrão Strategy te ajudaria bastante.

Resumidamente é isso aí :slight_smile:
Abraço!

[quote=Rodrigo Sasaki]Opa, que bom que conseguiu resolver :slight_smile: Mas segue umas dicas:

Para melhorar sua nota:

  • Nunca comece o nome de um método com letra em maiúsculo, é convencional começar com o nome minúsculo, e a cada troca de palavra a primeira letra é maiúscula. Ex: “openConnection”, “getPartialContent”. (Se eu fosse o professor eu me atentaria a isso)

Se tiver interesse em seguir carreira como programador:

  • Divida melhor seu código, cada classe deve ter uma única responsabilidade (SRP), deve ser coesa.
  • Pesquise por padrões para deixar seu código mais limpo e organizado, no caso o padrão Strategy te ajudaria bastante.

Resumidamente é isso aí :slight_smile:
Abraço![/quote]

Boa!
Tem material sobre OO nos livros
Java Use a Cabeça
e
Java Como Programar

Sobre padrões
tem o Design Patterns da Sierra também.

[quote=JavaDreams][quote=GabrielMantini]Cara, você precisa mesmo implementar isso? E se precisar, tem que ser em java?

Isso sai fácil usando arvore, mas fazer arvore em java…

Eu aconselho a fazer pseudocódigo mesmo, ou implementar em C ou Pascal, que ai você brinca com os ponteiros e todas essas palhaçadas. Mas aviso logo, é muito trabalhoso brincar disso…[/quote]

Por isso que não quis postar nada a mais que vídeos e sites com exemplos já feitos.
Vai saber a trabalheira que isso vai dar, sem contar que já pode existir uma pronta
para consulta didática.[/quote]