Dúvida num exemplo de um livro

Tem um exemplo de um livro, que não entendi como se faz, ele está meio confuso para mim que estou começando em java…tem como deixar ele mais acessivel ou mais claro para um iniciante??

Ele tem que fazer a verificação dos delimitadores de expressões que serão digitadas pelo usuario,Determine uma flag de saida de leitura para as expressões. Serão aceitos delimitadores validos {} [] ().Sendo que para cada delimitador de abertura devera ter um de saida correspondente.

[code]import java.io.*; // for I/O

class StackX
{
private int maxSize;
private char[] stackArray;
private int top;
//--------------------------------------------------------------
public StackX(int s)
{
maxSize = s;
stackArray = new char[maxSize];
top = -1;
}
//--------------------------------------------------------------
public void push(char j)
{
stackArray[++top] = j;
}
//--------------------------------------------------------------
public char pop()
{
return stackArray[top–];
}
//--------------------------------------------------------------
public char peek()
{
return stackArray[top];
}
//--------------------------------------------------------------
public boolean isEmpty()
{
return (top == -1);
}
//--------------------------------------------------------------
}

class BracketChecker
{
private String input;
//--------------------------------------------------------------
public BracketChecker(String in)
{ input = in; }
//--------------------------------------------------------------
public void check()
{
int stackSize = input.length();
StackX theStack = new StackX(stackSize);

  for(int j=0; j<input.length(); j++)   
     char ch = input.charAt(j);         
     switch(ch)
        {
        case '{':                     
        case '[':
        case '(':
           theStack.push(ch);           
           break;

        case '}':                     
        case ']':
        case ')':
           if( !theStack.isEmpty() )  
              {
              char chx = theStack.pop();   
              if( (ch=='}' && chx!='{') ||
                  (ch==']' && chx!='[') ||
                  (ch==')' && chx!='(') )
                 System.out.println("Error: "+ch+" em "+j);
              }
           else                        
              System.out.println("Erro: "+ch+" at "+j);
           break;
        default:    
           break;
        }   
     }  
  
  if( !theStack.isEmpty() )
     System.out.println("Erro: falta delimitador direito");
  }  

//--------------------------------------------------------------
}
////////////////////////////////////////////////////////////////
class BracketsApp
{
public static void main(String[] args) throws IOException
{
String input;
while(true)
{
System.out.print(
“Enter string contendo delimitadores: “);
System.out.flush();
input = getString();
if( input.equals(””) )
break;

     BracketChecker theChecker = new BracketChecker(input);
     theChecker.check();       
     }  
  }   

//--------------------------------------------------------------
public static String getString() throws IOException
{
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String s = br.readLine();
return s;
}
//--------------------------------------------------------------
}
[/code]

Opa, Beleza cara?

Pelo o que entendi da lógica do programa,
esse “troço estranho” foi feito verificar se a String com delimitadores passada foi bem formada, mas como assim?
Por exemplo, se você entrar com uma String contendo {}, como você pode ver ela é bem formada, todos os delimitadores foram abertos e fechados de forma correta, exemplos errados seriam {[){}()[]} ou {(]{)} entre outros, claro podendo haver outros caracteres no meio, mas os delimitadores teriam que ser fechados corretamente, como em uma expressão matématica, o programa mostraria como sendo válido ou inválido.

A Classe StackX, foi feita para funcionar como uma pilha(toda nova entrada deve ser colocada no topo, e toda retirada também tem que ser feita no topo, pense numa pilha de pratos, o melhor é sempre colocar um por um sempre no topo, e retirar um a um do topo =)),
o atributo stackArray funciona como pilha e temos os métodos, push que coloca um caracter na pilha e pop que retira, mas sempre tudo é feito no topo, existem algumas coisas a serem acrescentadas, como até onde sei não existem arrays dinâmicos, ou seja, seu tamanho não pode ser aumentado durante o tempo de execução, ele usa o atributo top para simular o top, ou seja, o atributo top, sempre vai estar apontando para o topo virtual.

A Classe BracketChecker, faz a parte da verificação dos Delimitadores, o método check faz todo o trabalho pesado, ele verifica caracter por caracter da String para verificar se foi bem formada.

for(int j=0; j<input.length(); j++)   
         char ch = input.charAt(j);         
         switch(ch)
            {
            case '{':                     
            case '[':
            case '(':
               theStack.push(ch);           
               break;

            case '}':                     
            case ']':
            case ')':
               if( !theStack.isEmpty() )  
                  {
                  char chx = theStack.pop();   
                  if( (ch=='}' && chx!='{') ||
                      (ch==']' && chx!='[') ||
                      (ch==')' && chx!='(') )
                     System.out.println("Error: "+ch+" em "+j);
                  }
               else                        
                  System.out.println("Erro: "+ch+" at "+j);
               break;
            default:    
               break;
            }   
         }  

Sei lá, se te ajudei.

Abraço.

É tipo assim se eu digitar a{b[c]}e ele tem que informar que está correto…

se eu digitar a[b{c}]} ele tem que informar que está errado…

só que no exemplo eu não entendi essas partes?

class BracketChecker { private String input; //-------------------------------------------------------------- public BracketChecker(String in) { input = in; }

[code]class BracketsApp
{
public static void main(String[] args) throws IOException
{
String input;
while(true)
{
System.out.print(
“Enter string contendo delimitadores: “);
System.out.flush();
input = getString();
if( input.equals(””) )
break;

     BracketChecker theChecker = new BracketChecker(input);   
     theChecker.check();     [/code]

public static String getString() throws IOException { InputStreamReader isr = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(isr); String s = br.readLine(); return s; }

Não teria um modo mais facil para faz isso?

[quote=alex_col10]É tipo assim se eu digitar a{b[c]}e ele tem que informar que está correto…

se eu digitar a[b{c}]} ele tem que informar que está errado…

só que no exemplo eu não entendi essas partes?

class BracketChecker { private String input; //-------------------------------------------------------------- public BracketChecker(String in) { input = in; }
[/quote]

class BracketChecker { private String input; //-------------------------------------------------------------- public BracketChecker(String in) { input = in; }

Isso aew, é um construtor, procure sobre eles tem várias coisas sobre esse assunto.
Mas, para te facilitar, um construtor define como um objeto vai ser criado, lembra quando você faz

new AlgumaClasse() ?
Você está chamando o construtor da classe.
Eles tem sempre o nome da Classe e não possuem retorno na assinatura.
Nesse exemplo, ele cria um construtor com parametro, ou seja, ele dá uma outra forma de criarmos objetos dessa classe.
se fizermos por exemplo

BracketChecker checker = new BracketChecker("{[a]a[b]}")

estamos usando esse Construtor, Ok?
mas e daí?
no bloco do construtor, temos o atributo private String input que recebe o valor do parametro do construtor , ou seja, toda a vez que criarmos um objeto com esse construtor, estaremos atribuindo um valor padrão ao atributo input.

public BracketChecker(String in) {
 input = in; 
}

[quote=alex_col10]É tipo assim se eu digitar a{b[c]}e ele tem que informar que está correto…
se eu digitar a[b{c}]} ele tem que informar que está errado…
só que no exemplo eu não entendi essas partes?

[code]class BracketsApp
{
public static void main(String[] args) throws IOException
{
String input;
while(true)
{
System.out.print(
“Enter string contendo delimitadores: “);
System.out.flush();
input = getString();
if( input.equals(””) )
break;

     BracketChecker theChecker = new BracketChecker(input);   
     theChecker.check();    

[/code]
[/quote]

Acredito não haver dúvida no public static void main(Sting… args) =)

while(true){}

looping eterno, acredito não haver dúvidas também

System.out.print("Enter string contendo delimitadores: ");   
System.out.flush();  

Operadores de saída do Sistema, print imprime, flush, acredito que libera o console para alguma coisa, como digitar entradas, mas não tenho certeza.

input = getString();         
if( input.equals("") )     
   break;   
BracketChecker theChecker = new BracketChecker(input);   
theChecker.check();

input, recebe uma entrada digitada no console, atraves do método getString().
se nada foi digitado o loop é interrompido, e a aplicação para.
lembra do construtores?
ele passa pelo construtor de BracketChecker o que foi lido no console.
Com o atributo private String input da classe BracketChecker devidamente populado, é feita a checagem para ver se é uma expressão bem formada.

Vou te fazer um proposta, para ver se você realmente entendeu esse negocio de construtores.

Mude sua classe BracketChecker para o seguinte.

class BracketChecker
   {
   private String input;                   

   public BracketChecker(String in)        
      { input = in; }
  public BracketChecker(){
  }
   public void check()
      {
      int stackSize = input.length();       
      StackX theStack = new StackX(stackSize); 

      for(int j=0; j<input.length(); j++)   
         char ch = input.charAt(j);         
         switch(ch)
            {
            case '{':                     
            case '[':
            case '(':
               theStack.push(ch);           
               break;

            case '}':                     
            case ']':
            case ')':
               if( !theStack.isEmpty() )  
                  {
                  char chx = theStack.pop();   
                  if( (ch=='}' && chx!='{') ||
                      (ch==']' && chx!='[') ||
                      (ch==')' && chx!='(') )
                     System.out.println("Error: "+ch+" em "+j);
                  }
               else                        
                  System.out.println("Erro: "+ch+" at "+j);
               break;
            default:    
               break;
            }   
         }  
      
      if( !theStack.isEmpty() )
         System.out.println("Erro: falta delimitador direito");
      }  
   } 

e troque a linha da Classe BracketsApp

BracketChecker theChecker = new BracketChecker(input); 

por

BracketChecker theChecker = new BracketChecker(); 

Veja os erros.

Bá tipo troquei algumas coisas, pra deixar ele mais claro…

[code]public class Pilha {

private int tamMax,topo;
private char memo[];

Pilha (int tamMax){
	
	this.tamMax = tamMax;
	this.memo = new char [this.tamMax];
	this.topo = -1;
	
}
public void push(char elemento){
	
	this.topo++;
	this.memo[this.topo]=elemento;
	
}
public char pop(){
	
	char elemento;
	elemento=this.memo[this.topo];
	this.topo--;
	return elemento;
	
}
public boolean isEmpty(){
	
	if (this.topo==-1){
		return true;
		
	}
	else
		return false;
		
}
public boolean isFull(){
	
	if (this.topo==this.tamMax-1){
		return true;
		
	}
	else
		return false;
}

}[/code]

[code]public class PilhaP {

private String entrada;


public PilhaP(String em){
	entrada=em;
	
}
public PilhaP(){
	
}
public void verificar(){
	
	int tamMax=entrada.length();
	Pilha a1= new Pilha(tamMax);
	
	for (int cont=0; cont<entrada.length(); cont++){
		
		char pal = entrada.charAt(cont);
		
		switch(pal)   
        {   
        case '{':                       
        case '[':   
        case '(':   
           a1.push(pal);             
           break;   

        case '}':                       
        case ']':   
        case ')':
        	
        	 if( !a1.isEmpty() )     
              {   
              char palx = a1.pop();     
              if( (pal=='}' && palx!='{') ||   
                  (pal==']' && palx!='[') ||   
                  (pal==')' && palx!='(') )   
                 System.out.println("Error: "+pal+" em "+cont);
                    
              } 
              else                           
              System.out.println("Erro: "+pal+" at "+cont);   
          	  break;   
        	  default:       
           	  break;	     
	}
}
if( !a1.isEmpty() )   
     System.out.println("Erro: falta delimitador direito");   

}
}[/code]

[code]public class Pilhaapp {

public static void main(String[] args) {
     
     String entrada;
     
     while (true){
     	
     	System.out.print("Enter string contendo delimitadores: ");   
                     
        System.out.flush();   
        entrada = getString();
                  
       if( entrada.equals("") )     
          break;   
                                 
     PilhaP a1 = new PilhaP();   
         
     }
}

}[/code]

Só que neste ultimo está dando erro no entrada=getString, mais na verdade eu quero que aparece uma caixa para mim digitar e não digitar ele lá embaixo…tenho que subistituir isso né?

e tá dando erro no getString(), pois você removeu o método da classe.
Comente essa linha ou coloque novamente o código do método.

import java.awt.Dimension;
import java.awt.GraphicsConfiguration;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;

public class Frame extends JFrame implements ActionListener {
    private JButton jButton1 = new JButton();
    private JTextField jTextField1 = new JTextField();

    public Frame(String string, GraphicsConfiguration graphicsConfiguration) {
        super(string, graphicsConfiguration);
    }

    public Frame(String string) {
        super(string);
    }

    public Frame(GraphicsConfiguration graphicsConfiguration) {
        super(graphicsConfiguration);
    }

    public Frame() {
        super();
        try {
            jbInit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    public static void main(String... args){
        new Frame();
    }
    
    public void actionPerformed(ActionEvent e) {
        if(this.jTextField1.getText().length() > 0){
            System.out.println(this.jTextField1.getText());
            BracketChecker theChecker = new BracketChecker(this.jTextField1.getText());  
            theChecker.check();     
        }
    }

    private void jbInit() throws Exception {
        this.getContentPane().setLayout(null);
        this.setSize(new Dimension(473, 107));
        
        jButton1.setText("Validar");
        jButton1.setBounds(new Rectangle(350, 30, 90, 25));
        jButton1.addActionListener(this);
        
        jTextField1.setBounds(new Rectangle(25, 30, 280, 25));
        this.getContentPane().add(jTextField1, null);
        this.getContentPane().add(jButton1, null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
    }
}

Construi esse Frame bem rapidamente, a saída ainda é no console.

Para capturar o que foi digitado é só ir no método public void actionPerformed(ActionEvent e)

Agora fiquei mais perdido do que cego em tiroteio :shock:

era por isso que o exemplo usava primariamente o console como input e output de mensagens,
para um iniciante, trabalhar com Componentes é um pouco complicado.

Mas basicamente, estou usando um componente Java chamado JFrame, ele é o básico para criar aplicações Desktop.

Mas como você é iniciante, se concentre no método actionPerformed, ignore o resto por enquanto =).
Outra coisa, para se pegar o que foi digitado use this.jTextField1.getText(), ele retorna tudo o que foi digitado no campo apos apertar o botão validar.

Ok?

Mais ali no metodo main, eu não poderia chamar com o import javax.swing.*; o campo para digitar?

Então, pelo o que entendi, você quer dizer se não posso apenas chamar um dos componentes, procede?

a reposta é não, para um input aparecer, temos que coloca-lo dentro de um container, o tal do JFrame faz esse papel.