Probleminha de lógica, alguém me ajuda?

18 respostas
dambros

Bom, dessa vez estou realmente perto de finalizar esse programa que está a alguns dias me assombrando, mas deparei-me com um probleminha de lógica.

Preciso apenas realizar três validações nesse código. Primeiro validar de o primeiro elemento da pilha não é um operando, então como verão abaixo tentei acrescentar o código:
if( ex.substring(0,1)=="+"||
                    ex.substring(0,1)=="-"||
                    ex.substring(0,1)=="*"||
                    ex.substring(0,1)=="/"){
                        valido = false;
                }

Mas acontece que aparentemente essa validação nunca é feita, pois independente do que eu entre como primeiro elemento sempre recebo a confimação de expressão válida.

E segundo eu precisaria verificar se o último elemento da pilha é um operando. Acontece que por mais que eu invoque o método "top()" sempre recebo o valor null como retorno.

E por fim precisaria verificar se tem 2 (ou mais) sinais consecutivos (exemplo A++B).

Alguma alma caridosa poderia me encaminhar a partir daqui?

Abaixo tem um pedaço do meu código onde é realizada a validação, imagino que seja o suficiente.

Agradeço desde já.

package Conversor;


import javax.swing.JOptionPane;


public class Conversor {
	private PilhaDin p = new PilhaDin();
        private ParteGrafica G = new ParteGrafica();
        private String po = "";
	private boolean valido = true;
	private String ex;
	private int pr;
	private Object x;
	private int pos = -1;

	public Conversor(String expressao) {
                setEx(expressao);
		                              
                if (Valida() == false) {
		JOptionPane.showMessageDialog(G.panel, "Por favor corrija a expressão");	
		}

		Converte();
		Operacao();
		
	}

	public boolean Valida() {
		int j = 1;     
                                
                for (int i = 0; i < ex.length(); i++) {
			if (ex.substring(i, j).equals("(")) {
				p.push(ex.substring(i, j));
			}
			if (ex.substring(i, j).equals(")")) {
				if (p.isEmpty() == true) {
					valido = false;
                                }else {
					p.pop();
				}
                                
			}
			j++;
                         
		}
                
                if( ex.substring(0,1)=="+"||
                    ex.substring(0,1)=="-"||
                    ex.substring(0,1)=="*"||
                    ex.substring(0,1)=="/"){
                        valido = false;
                }                
                                              
		if (p.isEmpty() != true) {
			valido = false;
		}
		if (valido == true) {
			JOptionPane.showMessageDialog(G.panel, "Expressão Válida");
                    return true;
		} else {
			JOptionPane.showMessageDialog(G.panel, "Expressão Inválida");
                    return false;
		}

	}

	public int prioridade(Object op) {

		if (op.equals("("))
			return 1;
		if (op.equals("+") || op.equals("-"))
			return 2;
		if (op.equals("*") || op.equals("/"))
			return 3;
		return 0;
	}

	public void Converte() {
		Object[] npos = new Object[ex.length()];
		String[] infixa = new String[ex.length()];
		int j = 1;
		for (int i = 0; i < ex.length(); i++) {
			infixa[i] = ex.substring(i, j);
			j++;

		}
		for (int i = 0; i < infixa.length; i++) {
			if (infixa[i].equalsIgnoreCase("A")
					|| infixa[i].equalsIgnoreCase("B")
					|| infixa[i].equalsIgnoreCase("C")
					|| infixa[i].equalsIgnoreCase("D")
					|| infixa[i].equalsIgnoreCase("E")
					|| infixa[i].equalsIgnoreCase("F")
					|| infixa[i].equalsIgnoreCase("G")
					|| infixa[i].equalsIgnoreCase("H")
					|| infixa[i].equalsIgnoreCase("I")
					|| infixa[i].equalsIgnoreCase("J")
					|| infixa[i].equalsIgnoreCase("K")
					|| infixa[i].equalsIgnoreCase("L")
					|| infixa[i].equalsIgnoreCase("M")
					|| infixa[i].equalsIgnoreCase("N")
					|| infixa[i].equalsIgnoreCase("O")
					|| infixa[i].equalsIgnoreCase("P")
					|| infixa[i].equalsIgnoreCase("Q")
					|| infixa[i].equalsIgnoreCase("R")
					|| infixa[i].equalsIgnoreCase("S")
					|| infixa[i].equalsIgnoreCase("T")
					|| infixa[i].equalsIgnoreCase("U")
					|| infixa[i].equalsIgnoreCase("V")
					|| infixa[i].equalsIgnoreCase("X")
					|| infixa[i].equalsIgnoreCase("W")
					|| infixa[i].equalsIgnoreCase("Y")
					|| infixa[i].equalsIgnoreCase("Z")) {

				pos++;
				npos[pos] = infixa[i];

			} else if (infixa[i].equals("+") || infixa[i].equals("-")
					|| infixa[i].equals("/") || infixa[i].equals("*")) {
				pr = prioridade(infixa[i]);

				while (p.isEmpty() != true && prioridade(p.top()) >= pr) {
					pos++;
					npos[pos] = p.pop();
				}
				p.push(infixa[i]);
			} else if (infixa[i].equalsIgnoreCase("(")) {
				p.push(infixa[i]);
			} else if (infixa[i].equalsIgnoreCase(")")) {
				x = p.pop();
				while (!x.equals("(")) {
					pos++;
					npos[pos] = x;
					x = p.pop();
				}

			}

		}
		while (p.isEmpty() != true) {
			pos++;
			npos[pos] = p.pop();

		}
		for (int i = 0; i < npos.length; i++) {
			if (npos[i] == null) {
				npos[i] = "";
			}
			po = po + npos[i];

		}

	}

	public void Operacao() {
		p.init();
		String[] infixa = new String[ex.length()];
		double[] val_infixa = new double[ex.length()];
		int j = 1;
		for (int i = 0; i < po.length(); i++) {
			infixa[i] = po.substring(i, j);
			j++;

		}
		for (int i = 0; i < po.length(); i++) {
			if (infixa[i].equalsIgnoreCase("A")
					|| infixa[i].equalsIgnoreCase("B")
					|| infixa[i].equalsIgnoreCase("C")
					|| infixa[i].equalsIgnoreCase("D")
					|| infixa[i].equalsIgnoreCase("E")
					|| infixa[i].equalsIgnoreCase("F")
					|| infixa[i].equalsIgnoreCase("G")
					|| infixa[i].equalsIgnoreCase("H")
					|| infixa[i].equalsIgnoreCase("I")
					|| infixa[i].equalsIgnoreCase("J")
					|| infixa[i].equalsIgnoreCase("K")
					|| infixa[i].equalsIgnoreCase("L")
					|| infixa[i].equalsIgnoreCase("M")
					|| infixa[i].equalsIgnoreCase("N")
					|| infixa[i].equalsIgnoreCase("O")
					|| infixa[i].equalsIgnoreCase("P")
					|| infixa[i].equalsIgnoreCase("Q")
					|| infixa[i].equalsIgnoreCase("R")
					|| infixa[i].equalsIgnoreCase("S")
					|| infixa[i].equalsIgnoreCase("T")
					|| infixa[i].equalsIgnoreCase("U")
					|| infixa[i].equalsIgnoreCase("V")
					|| infixa[i].equalsIgnoreCase("X")
					|| infixa[i].equalsIgnoreCase("W")
					|| infixa[i].equalsIgnoreCase("Y")
					|| infixa[i].equalsIgnoreCase("Z")) {
									
						val_infixa[i] = Double.parseDouble(JOptionPane
								.showInputDialog(G.frame,"Digite o valor de: "
									+ infixa[i]));
                            
						p.push(val_infixa[i]);


			} else if (infixa[i].equals("+") || infixa[i].equals("-")
					|| infixa[i].equals("/") || infixa[i].equals("*")) {
				Double x1 = (Double) p.pop();
				Double y = (Double) p.pop();

				if (infixa[i].equals("+")) {
					p.push(x1.doubleValue() + y.doubleValue());
				}
				if (infixa[i].equals("-")) {
					p.push(x1.doubleValue() - y.doubleValue());
				}
				if (infixa[i].equals("*")) {
					p.push(x1.doubleValue() * y.doubleValue());
				}
				if (infixa[i].equals("/")) {
					p.push(x1.doubleValue() / y.doubleValue());
				}

			}
		}
		Object resultado = p.pop();
             
                G.TextFieldPosFixa.setText(po);
                String strResul = resultado.toString();
                G.TextFieldResultado.setText(strResul);
                
                
        }       
                
   
	public void setEx(String ex) {
		this.ex = ex;
	}

}

18 Respostas

CintiaDR

Eu não li tudo, mas de cara

if( ex.substring(0,1)=="+"||  
 ex.substring(0,1)=="-"||  
 ex.substring(0,1)=="*"||  
 ex.substring(0,1)=="/"){  
             valido = false;  
       }

Sempre vai dar false.

Vc não deve usar o “==” para comparar Strings, e sim “equals()”. O “==” serve pra tipos básicos, tipo int, char… Você pode usar o método"chatAt" pra pegar caracter.

Veja se é isso. Se não for, depois eu volto aqui e vejo de novo o seu super-post.

GustavoLaguna

cara, quando fiz algo desse tipo (compilador) eu usei automatos que facilitou bastante… dei uma olhada rápida no seu código e não vi uma estrutura desse tipo… vou tentar ver na hora do almoço aqui.

dambros

CintiaDR:
Eu não li tudo, mas de cara

if( ex.substring(0,1)=="+"||  
 ex.substring(0,1)=="-"||  
 ex.substring(0,1)=="*"||  
 ex.substring(0,1)=="/"){  
             valido = false;  
       }

Sempre vai dar false.

Vc não deve usar o “==” para comparar Strings, e sim “equals()”. O “==” serve pra tipos básicos, tipo int, char… Você pode usar o método"chatAt" pra pegar caracter.

Veja se é isso. Se não for, depois eu volto aqui e vejo de novo o seu super-post.

Grande garoto, consegui resolver um dos problemas!

2 more to go!

Existe alguma forma de eu parar a execução da tarefa e recomeçar (sem precisar finalizar o programa)?

Porque ele está mostrando que a expressão é invalida, mas mesmo assim da continuidade no processo.

F

Olá.

Para vc controlar a execução de uma parte do programa sem ter que encerrá-lo, vc pode utilizar threads. Dê uma pesquisada geral neste fórum que vc vai encontrar muita coisa, inclusive códigos de exemplo.

Abraço.

dambros

flaviosf:
Olá.

Para vc controlar a execução de uma parte do programa sem ter que encerrá-lo, vc pode utilizar threads. Dê uma pesquisada geral neste fórum que vc vai encontrar muita coisa, inclusive códigos de exemplo.

Abraço.

Jesuis nunca mexi com isso na vida Oo ferro.

CintiaDR

Bom, para “parar” a execução vc pode lançar exceção e capturar no método acima. Só que não dá pra voltar a executar daonde vc parou, né hehehehehe Mas daria pra chamar o método novamente.

CintiaDR

É eu também usei automatos, mas aparentemente o problema dele é só com expressões numéricas. E eu montava uma árvore de execução, e não uma pilha. Pra ser sincera não entendi a solução dele :slight_smile: Mas também não parei para analisar.

Eu até cheguei a usar o Yacc (bons/maus tempos de C… heheheeh)

dambros

CintiaDR:
Bom, para “parar” a execução vc pode lançar exceção e capturar no método acima. Só que não dá pra voltar a executar daonde vc parou, né hehehehehe Mas daria pra chamar o método novamente.

Eu pensei nisso, mas o problea que não tem exatamente um “método acima”, tudo começa com uma ação em um botão e o resto é tudo consequência.

É um método chamando o outro, e não tem um onde que eu chamasse começaria novamente.

CintiaDR
try{
if (Valida() == false) {  
       JOptionPane.showMessageDialog(G.panel, "Por favor corrija a expressão");      
      }  
  
    Converte();  
    Operacao();  
} catch (Exception e){
    // sei lá, senta e chora, etc
}
victorwss

dambros:
if (infixa[i].equalsIgnoreCase("A") || infixa[i].equalsIgnoreCase("B") || infixa[i].equalsIgnoreCase("C") || infixa[i].equalsIgnoreCase("D") || infixa[i].equalsIgnoreCase("E") || infixa[i].equalsIgnoreCase("F") || infixa[i].equalsIgnoreCase("G") || infixa[i].equalsIgnoreCase("H") || infixa[i].equalsIgnoreCase("I") || infixa[i].equalsIgnoreCase("J") || infixa[i].equalsIgnoreCase("K") || infixa[i].equalsIgnoreCase("L") || infixa[i].equalsIgnoreCase("M") || infixa[i].equalsIgnoreCase("N") || infixa[i].equalsIgnoreCase("O") || infixa[i].equalsIgnoreCase("P") || infixa[i].equalsIgnoreCase("Q") || infixa[i].equalsIgnoreCase("R") || infixa[i].equalsIgnoreCase("S") || infixa[i].equalsIgnoreCase("T") || infixa[i].equalsIgnoreCase("U") || infixa[i].equalsIgnoreCase("V") || infixa[i].equalsIgnoreCase("X") || infixa[i].equalsIgnoreCase("W") || infixa[i].equalsIgnoreCase("Y") || infixa[i].equalsIgnoreCase("Z")) {

Fica melhor assim:

if (infixa[i].matches("[A-Za-z]")) {

dambros:
} else if (infixa[i].equalsIgnoreCase("(")) { p.push(infixa[i]); } else if (infixa[i].equalsIgnoreCase(")")) {

Não precisa de equalsIgnoreCase aí. Só equals já está ok.

dambros
CintiaDR:
try{
if (Valida() == false) {  
       JOptionPane.showMessageDialog(G.panel, "Por favor corrija a expressão");      
      }  
  
    Converte();  
    Operacao();  
} catch (Exception e){
    // sei lá, senta e chora, etc
}

Problema qe se eu fizer dessa forma não tem como eu recomeçar... o que eu devo chamar novamente?

E outra coisa, agora que eu vi, quando mando calcular, ele abre outra janela do programa em vez de ficar tudo na mesma!

CintiaDR

Eu manjo nada de swing. Nadica de nada.

Mas imagino que os métodos são chamados dependendo de ações (tipo, o cara apertou o botão “Calcular”). Então em caso de erro, vc mostra o erro e espera ele corrigir e apertar o botão de novo, não seria isso??

dambros

CintiaDR:
Eu manjo nada de swing. Nadica de nada.

Mas imagino que os métodos são chamados dependendo de ações (tipo, o cara apertou o botão “Calcular”). Então em caso de erro, vc mostra o erro e espera ele corrigir e apertar o botão de novo, não seria isso??

Na verdade da forma que está estruturado funciona da seguinte forma:

Ele preenche uma JTextField e ao apertar Um botao todo o cálculo começa.

Primeiro é verificado a validez do que foi entrado. Se for válido ele exibe a mensagem de OK e da continuidade no processo. E se for inválido é o oposto. Ele exibe a mensagem de erro, mas como vc pode ver nocódigo que postei logo apos ele exibir tal mensagem, ele invoca o metodo seguinte e da continuidade no processo.

Eu queria que ele mostrasse a mensagem e parasse por ae, dai reiniciasse.

thegoergen

dambros:
CintiaDR:
Bom, para “parar” a execução vc pode lançar exceção e capturar no método acima. Só que não dá pra voltar a executar daonde vc parou, né hehehehehe Mas daria pra chamar o método novamente.

Eu pensei nisso, mas o problea que não tem exatamente um “método acima”, tudo começa com uma ação em um botão e o resto é tudo consequência.

É um método chamando o outro, e não tem um onde que eu chamasse começaria novamente.

Então seria bom dividir em métodos… Para poder fazer isso…

dambros

thegoergen:
dambros:
CintiaDR:
Bom, para “parar” a execução vc pode lançar exceção e capturar no método acima. Só que não dá pra voltar a executar daonde vc parou, né hehehehehe Mas daria pra chamar o método novamente.

Eu pensei nisso, mas o problea que não tem exatamente um “método acima”, tudo começa com uma ação em um botão e o resto é tudo consequência.

É um método chamando o outro, e não tem um onde que eu chamasse começaria novamente.

Então seria bom dividir em métodos… Para poder fazer isso…

É eu pensei nisso, mas se de pensar em remanejar todo aquele trabalho… me desânima. Talvez eu tente usar esses Thread que referiram, mas vou precisar aprender sobre, já é um bom motivo para aprender algo novo.

victorwss

dambros:
thegoergen:
dambros:
CintiaDR:
Bom, para “parar” a execução vc pode lançar exceção e capturar no método acima. Só que não dá pra voltar a executar daonde vc parou, né hehehehehe Mas daria pra chamar o método novamente.

Eu pensei nisso, mas o problea que não tem exatamente um “método acima”, tudo começa com uma ação em um botão e o resto é tudo consequência.

É um método chamando o outro, e não tem um onde que eu chamasse começaria novamente.

Então seria bom dividir em métodos… Para poder fazer isso…

É eu pensei nisso, mas se de pensar em remanejar todo aquele trabalho… me desânima. Talvez eu tente usar esses Thread que referiram, mas vou precisar aprender sobre, já é um bom motivo para aprender algo novo.

Tente simplificar e não complicar!

Dividir em métodos menores = simplificar
Usar threads = complicar

dambros

victorwss:
dambros:
thegoergen:
dambros:
CintiaDR:
Bom, para “parar” a execução vc pode lançar exceção e capturar no método acima. Só que não dá pra voltar a executar daonde vc parou, né hehehehehe Mas daria pra chamar o método novamente.

Eu pensei nisso, mas o problea que não tem exatamente um “método acima”, tudo começa com uma ação em um botão e o resto é tudo consequência.

É um método chamando o outro, e não tem um onde que eu chamasse começaria novamente.

Então seria bom dividir em métodos… Para poder fazer isso…

É eu pensei nisso, mas se de pensar em remanejar todo aquele trabalho… me desânima. Talvez eu tente usar esses Thread que referiram, mas vou precisar aprender sobre, já é um bom motivo para aprender algo novo.

Tente simplificar e não complicar!

Dividir em métodos menores = simplificar
Usar threads = complicar

O problema que sinceramente eu não sei como conseguir manipular isso para que fique de uma forma que de para chamar novamente. Eu sofri bastante para chegar nesse algoritmo ja e tentei fazer o máximo possível para que pudesse ser remanejado caso precisasse (joguei 2 códigos fora exatamente por não conseguir fazer isso).

CintiaDR

De novo, eu não sei Swing, mas não seria só fazer isso aqui?? Se não for, desculpa, eu realmente não entendi seu problema…

public Conversor(String expressao) {  
         setEx(expressao);  
                                         
         if (Valida() == false) {  
             JOptionPane.showMessageDialog(G.panel, "Por favor corrija a expressão");      
         }  else { 
             Converte();  
             Operacao();  
         }
     }

Aproveita e posta de novo quais são seus problemas atuais que já me perdi hahahahahahahah

Criado 18 de abril de 2008
Ultima resposta 19 de abr. de 2008
Respostas 18
Participantes 6