Ho un problema, grande con un esercizio sugli alberi, è questo:
L'interfaccia è:codice:Si realizzi un'implementazione dell'interfacce Tree<E>, mostrata nella pagine seguente, che rappresenti un albero radicato generico. Si realizzi anche una classe Java denominata Triple, che rappresenti una tripla di valori interi compresi tra 1 e 9 (estremi inclusi). In seguito si realizzi un programma Java che preso in input un file contenente una lista di triple costruisca un albero completo (Tree<Triple>) dove ogni nodo possiede un numero costante di figli. Gli elementi verranno forniti in ordine nella lista in modo da costruire l'albero inserendo i valori nei nodi procedendo attraverso una visita postorder dell'albero. Il programma dovrà stampare in un file di output la visita preorder dell'albero ottenuto, utilizzando il metodo toString() fornito dalla classe Tree. Input Il file di input contiene una lista di terne di valori interi, una per riga, racchiuse tra parentesi. La prima riga del file contiene due valori interi, separati da una virgola, che specificano l'altezza dell'albero e il numero di figli di ciascun nodo. Output Il file di output dovrà contenere una lista di triple, una per riga, racchiuse tra parentesi e risultanti dalla visita preorder dell'albero ottenuto.
Ora, io ho pensato di realizzare l'albero con array, praticamente contiene elementi di tipo TNode, a sua volta di tipo Tripla. Quindi la classe TNode lavorerà con dei parametri che sono indice, che indicano la posizione nell'array del fratello, genitore, eccetera.codice:public interface Tree<E> { public int size(); // ritorna il numero di nodi presenti nell'albero public String toString(); // stampa l'albero, un elemento per riga, utilizzando una visita poreorder public E[] preorder(); // ritorna un array contenente tutti i nodi dell'albero ordinati in base ad una visita preorder public E[] inorder(); // ritorna un array contenente tutti i nodi dell'albero ordinati in base ad una visita inorder }
Riporto tutte le classi, ma il problema si presenta nella classe Albero nel toString, dove c'è un NullPointerException.
classe Tripla
[code]codice:public class Triple<E> { int primo, secondo, terzo; public Triple(int primo, int secondo, int terzo) { this.primo=primo; this.secondo=secondo; this.terzo=terzo; } public int getPrimo(){return primo;} public int getSecondo(){return secondo;} public int getTerzo(){ return terzo;} public void setPrimo(int primo){this.primo=primo;} public void setSecondo(int secondo){this.secondo=secondo;} public void setTerzo(int terzo){this.terzo=terzo;} public String toString() { return "("+getPrimo()+","+getSecondo()+","+getTerzo()+")"; } }
class TNode
il Maincodice:public class TNode<E> { private Triple<E> element; private int sons; private int firstSon; private int sibling; private int parent; private int level; public TNode(Triple<E> element) { this.element=element; sons=0; firstSon=-1; sibling=-1; parent=-1; level=-1; } public Triple<E> getElement(){return element;} public int getSons(){return sons;} public void setfirstSon(int firstSon){this.firstSon=firstSon;} public int getfirstSon(){return firstSon;} public void setsibling(int sibling){this.sibling=sibling;} public int getsibling(){return sibling;} public int getparent(){return parent;} public void setparent(int i){parent=i;} public void increasesons(){sons++;} public void setlevel(int level){this.level=level;} public int getlevel(){return level;} }
classe Alberocodice:import java.io.*; import java.util.StringTokenizer; public class Main { public static void main(String [] args) { Main main=new Main(); long start=System.currentTimeMillis(); main.TreeBuilding("input.txt","output.txt"); long end=System.currentTimeMillis(); System.out.println("Il tempo d'esecuzione del programma è "+(end-start)+" ns"); } public void TreeBuilding(String input, String output) { PrintWriter out=null; FileReader reader=null; BufferedReader buff=null; StringTokenizer str=null; try{ out=new PrintWriter(output); reader=new FileReader(input); buff=new BufferedReader(reader); String current=""; current=buff.readLine(); //tripla corrente int altezza=current.charAt(0); //i primi dati che leggerò saranno questi int figli=current.charAt(2); int nodi=0; while(buff.ready()){ current=buff.readLine(); //faccio la lettura per contare quanti nodi ci sono nodi++; } Albero<TNode> albero=new Albero(altezza, nodi); reader=new FileReader(input); buff=new BufferedReader(reader); //reinizializzo e faccio una prima lettura perchè la prima stringa non mi serve buff.readLine(); while(buff.ready()){ current=buff.readLine(); //memorizzo la stringa corrente str=new StringTokenizer(current, "(,)"); int primo=Integer.parseInt(str.nextToken()); int secondo=Integer.parseInt(str.nextToken()); int terzo=Integer.parseInt(str.nextToken()); Triple tripla=new Triple(primo, secondo, terzo); TNode nodo=new TNode(tripla); albero.addNode(nodo); } out.print(albero.toString()); } catch(FileNotFoundException e1) { System.out.println("Error...file not found"); } catch(IOException e2) { System.out.println("Error...input/output"); } finally{ try{ reader.close(); buff.close(); out.close(); } catch(IOException e4) { System.out.println("Error...it is not possible to close files"); } } } }
Ecco gli errori:codice:interface Tree<E> { public int size(); // ritorna il numero di nodi presenti nell'albero public String toString(); // stampa l'albero, un elemento per riga, utilizzando una visita postorder public E[] preorder(); // ritorna un array contenente tutti i nodi dell'albero ordinati in base ad una visita preorder public E[] inorder(); // ritorna un array contenente tutti i nodi dell'albero ordinati in base ad una visita inorder } public class Albero<E> implements Tree<E> { private int size; private TNode<E> root; private int height; private TNode<E>[] albero; //vorrei usare un array di tipo TNode<E> private int nodi; public Albero(int height, int nodi) //l'albero avrà la sua altezza e un certo numero di nodi { size=0; root=null; albero= new TNode[nodi]; this.height=height; } public int size(){return size;} public void addNode(TNode<Triple<E>> nodo){ if(size==0) //inserisco la radice { root=(TNode<E>)nodo; root.setfirstSon(1); //setto il suo primo figlio nodo.setparent(0); //setto il padre root.increasesons(); //incremento il numero di figli root.setlevel(0); //livello della radice albero[0]=root; //inserisco nell'array nodo.setlevel(1); //livello del figlio size++; } else{ for(int i=0; i<albero.length; i++) { if(albero[i]!=null){ if(albero[i].getSons()==0 && albero[i].getlevel()!=height) //se il nodo non ha figli e non siamo in una foglia { albero[i].setfirstSon(i+albero[i-1].getfirstSon()); //setto l'inice del primofiglio di albero[i] albero[albero[i].getfirstSon()]=(TNode<E>)nodo; //setto il figlio albero[albero[i].getfirstSon()].setsibling(albero[i].getfirstSon()+1); //setto l'indice del fratello del figlio...... albero[albero[i].getfirstSon()].setparent(i); //setto l'indice del padre di questo figlio albero[albero[i].getfirstSon()].setlevel(albero[i].getlevel()+1); //setto il livello del figlio albero[i].increasesons(); //incremento il contatore dei figli del nodo di partenza size++; } else if(albero[i].getSons()>=1 && albero[i].getSons()<4 && albero[i].getlevel()!=height) //se il numero dei figli e maggiore uguale ad 1 e minore di 4 ne devo inserire ancora di figli { int dad=i; //memorizzo l'indice del padre i=albero[i].getfirstSon(); //indice del figlio while(albero[i]!=null) //finchè ci sono figli vai alle altre posizioni i++; albero[i]=(TNode<E>)nodo; //e poi faccio setto l'elemento, albero[i].setsibling(i+1); //il fratello albero[i].setparent(dad); // il genitore albero[i].setlevel(albero[dad].getlevel()+1); //il livello albero[i].increasesons(); //incremento il contatore di figli del nodo di partenza size++; } } } } } public String toString() { String toReturn=""; E[] elemArray = preorder(); for(int i=0; i<elemArray.length; i++) toReturn+=elemArray[i].toString()+'\r'+'\n'; //qui c'è l'errore return toReturn; } public E[] preorder() { E[] elemArray =(E[]) new Object[size]; //memorizzerà gli elementi dell'albero in un array ordinato secondo la visita preorder int index=0; int i=0; int j=0; elemArray[index]=(E)albero[0]; while(i<albero[0].getSons()-1) { while(albero[j].getfirstSon()!=-1) { j=albero[j].getfirstSon(); elemArray[index++]=(E)albero[j]; } while(albero[j].getsibling()!=-1) elemArray[index++]=(E)albero[j++]; elemArray[index++]=(E)albero[j++]; //ultimo fratello da inserire nell'array i++; j=i+1; //l'indice del fratello dei figli della radice; } return elemArray; } public E[] inorder(){ E[] elemArray =(E[]) new Object[size]; //memorizzerà gli elementi dell'albero in un array ordinato secondo la visita inorder int index=0; int i=0; int j=0; int ultimo=0; while(i<albero[0].getSons()-1) { while(albero[j].getfirstSon()!=-1) j=albero[j].getfirstSon(); ultimo=j; while(albero[j].getparent()!=0){ elemArray[index++]=(E)albero[j]; j=albero[j].getparent(); } elemArray[index++]=(E)albero[j]; if(i==0) elemArray[index++]=(E)albero[0]; while(albero[ultimo].getsibling()!=-1){ elemArray[index++]=(E)albero[albero[ultimo].getsibling()]; ultimo++; } i++; j=i+1; } return elemArray; } public E[] postorder(){ E[] elemArray =(E[]) new Object[size]; //memorizzerà gli elementi dell'albero in un array ordinato secondo la visita postorder int index=0; int i=0; int j=0; while(i<albero[0].getSons()-1) { while(albero[j].getfirstSon()!=-1) j=albero[j].getfirstSon(); while(albero[j].getsibling()!=-1) elemArray[index++]=(E)albero[j++]; elemArray[index++]=(E)albero[j]; elemArray[index++]=(E)albero[albero[j].getparent()]; i++; j=i+1; } return elemArray; } }
Sbaglio forse l'inseirmento, non so dove mettere mani sinceramente, temo ci siano molte cose pensate male...mi aiutereste?codice:Exception in thread "main" java.lang.NullPointerException at Albero.toString(Albero.java:94) at Main.TreeBuilding(Main.java:63) at Main.main(Main.java:10) >Exit code: 1
Grazie.

Rispondi quotando