PDA

View Full Version : [Java] Alberi Binari: Ridefinire Iteratore per visita Postfissa


luxorl
18-08-2008, 12:14
Ciao a tutti.
Ho ridefinito l'Iterator di Java per poter iterare su un albero binario.
Ho alcuni problemi a far muovere l'iteratore mediante visita postfissa.
In particolare, sulle foglie ho implementato i seguenti metodi:

public class ICostante extends IEspressione implements Iterator<Espressione> {

boolean flag=true;

public ICostante(Costante c) {
this.exp=c;
//this.it=c.iterator();
}

public boolean hasNext() { return this.flag; }

public Espressione next() {
if(flag){
this.flag=false;
return exp;
}

throw new NoSuchElementException();
}

}

Mentre nei nodi non terminali ho scritto questo codice:


public class IOperatorePostfisso extends IOperatore {

private final int SINISTRA=0, DESTRA=1;
private int puntatore=SINISTRA;

public IOperatorePostfisso(Operatore o) {
super(o);
}

public boolean hasNext(){
if(puntatore==DESTRA) return it.hasNext();
return true;
}

public Espressione next(){
if(it==null) this.it=exp.getLeft().iterator();
if(it.hasNext()) return it.next();
if(puntatore==SINISTRA){
puntatore=DESTRA;
it=exp.getRight().iterator();
if(it.hasNext()) return it.next();
else return exp; //nodo non terminale operatore
}

throw new NoSuchElementException();

}
Però ho problemi a ridefinirmi il next(). Ho provato in questo modo ma mi ritorna (con visita postfissa) solo le foglie. :confused: :confused:

Per esempio se inserisco la seguente espressione: 4+5*3
L'iteratore mi stampa: 4 5 3

Perché non mi ritorna mai exp quando è un operatore? :(

luxorl
18-08-2008, 12:54
Allora, ho capito l'errore che sta nel metodo hasNext()
Che in caso di Puntatore a destra non deve ritornare l'hasNext() del figlio ma una propria flag che segnala se l'operatore stesso è stato già ritornato.
Questo perché nella visita postfissa l'ultimo ad essere ritornato è il nodo padre e non il figlio destro. A parole non mi spiego molto bene meglio incollare il codice corretto.

public class IOperatorePostfisso extends IOperatore {

private final int SINISTRA=0, DESTRA=1;
private int puntatore=SINISTRA;
private boolean flag=false;

public IOperatorePostfisso(Operatore o) {
super(o);
}

public boolean hasNext(){
if(puntatore==DESTRA) return !flag;
return true;
}

public Espressione next(){
if(it==null) this.it=exp.getLeft().iterator();
if(it.hasNext()) return it.next();
if(puntatore==SINISTRA){
puntatore=DESTRA;
it=exp.getRight().iterator();
if(it.hasNext()) return it.next();
}
if(puntatore==DESTRA){
flag=true;
return exp;
}

throw new NoSuchElementException();

}

Prima non mi stampava mai l'operatore perché quando il padre chiedeva hasNext sul figlio questo lo richiedeva al suo figlio DX e se questo tornava false, perché era stato già restituito, e il metodo next() non veniva proprio invocato sull'operatore.