PDA

View Full Version : [JAVA] Problema iteratore e consiglio strategia per risolvere un problema:


e-commerce84
04-06-2009, 10:48
Ciao,
ho scritto una classe chiamata Involucro2 che mi rappresentava insiemi di stringhe in cui la i-esima stringa era totalmente contenuta nella (i+1)-esima stringa quindi cose del tipo: {a, ab, cab, cabz}

Il codice della classe è il seguente (sono poche righe,c'è tanta documentazione pechè la proff la vuole), ho un paio di problemi...


import java.util.*;

public class Involucro2{
/** OVERVIEW: Involucro rappresenta una collezione dinamica di stringhe del tipo <s1, s2, s3,...., sn> tali che
s_i è completamente contenuta in s_(i+1).

V = {{s1,s2,s3,...,sn>: Per ogni i s_i è una stringa ed s_i è interamente contenuto in s_(i+1)}}

O = inserisci: Se l'oggetto che si vuole inserire è coerente con la rappresentazione della collezione
(è una stringa) e con lo stato attuale della collezione (i valori già presenti nella
collezione), allora lo inserisce nella collezione modificandola

fondi: Date collezioni S e T se s_n è interamente contenuto in t_1 allora fonde le due collezioni nel
seguente modo: S = <s1,s2,s3,...,sn> T = {t1,t2,t3,...,tn} --> {s1,s2,s3,...,sn,t1,t2,t3,..,tn}

get(i): Accede in maniera posizionale all'i-esimo elemento della collezione */

Vector collStr; // Rappresenta la collezione di stringhe


/** FUNZIONE DI ASTRAZIONE: F_a(): STATO CONCRETO ----> STATO ASTRATTO
F_a([a, ab, abc, abcd]) ------> {<a, ab, abc, abcd>}
ma anche: F_a([a, b(a), (ba)f, z(baf), (zbaf)e]) ---> {a, ba, baf, zbaf, zbafe}

INVARIANTE DI RAPPRESENTAZIONE: è un predicato I: C ---> boolean che è vero per gli stati concreti che sono
rappresentazioni leggittime di uno stato astratto:

I(collStr): collStr != NULL (il Vector deve essere sempre diverso da NULL)
Per ogni i: v.get(i) deve essere incluso in v.get(i+1) (la i-esima stringa deve
sempre essere interamente contenuta nella (i+1)-esima stringa della collezione */

/** COSTRUTTORE:
EFFECTS: Crea un nuovo oggetto di tipo Involucro che rappresenta la collezione vuota
@param: void:
@return: Il riferimento ad un oggetto di tipo Involucro
Il costruttore soddisfa l'invariante di rappresentazione in quanto: 1) Viene assegnata alla variabile di istanza
collStr il riferimento ad un nuovo Vector quindi no è mai null. 2) Il costruttore crea una collezione vuota che
rappresenta la stringa vuota contenuta in ogni stringa, quindi qualsiasi sia il primo elemento va bene */

public Involucro2(){
collStr = new Vector(); // Crea la collezione vuota assegnando a collStr il riferimento ad un nuovo Vector vuoto
}

/** Metodo inserisci()
EFFECTS: Se il parametro può essere inserito nella collezione (se contiene completamente l'ultima stringa della
collezione, allora viene inserito nella collezione rappresentata dall'oggetto ricevente, altrimenti viene
sollevata una StringaNonValidaException
MODIFIES: this
@param: Un oggetto di tipo String
Il metodo inserisci() soddisfa l'invariante di rappresentazione in quanto se la collezione è vuota permette
l'inserimento di una stringa qualsiasi, se invece nella collezione è già presente qualcosa prima di inserire il
parametro controlla che il parametro contiene completamente l'ultima stringa presente nella collezione. Se ciò è
verificato la inserisce, altrimenti no e la collezione rimane sempre coerente con la sua definizione */

public void inserisci(String str){

int dimensione = collStr.size() ; // Contiene la dimensione del Vector collStr
String ultima = (String)collStr.elementAt(dimensione);
if(dimensione == 0) // Se la collezione è vuota
collStr.addElement(str); // Aggiungi la stringa parametro in prima posizione

else{ // Altrimenti, se nella collezione ci sono già degli elementi
if(str.contains(ultima)) // Se il parametro contiene l'ultima stringa della collezione
collStr.addElement(str); // Aggiungi la stringa parametro in prima posizione
else throw new StringaNonValidaException(); // altrimenti solleva un'eccezione
}
}



/** Metodo fondi():
EFFECTS: Se possibile fonde la collezione ricevente con quella referenziata dal parametro. Tale fusione è possibile
se e solo se l'ultimo elemento della collezione ricevente è totalmente contenuto nel primo elemento della
collezione referenziata dal parametro, altrimenti solleva una CollezioneParametroNonValidaExcepion
Eventualmente la dusione fosse possiebileil metodo crea una nuova collezione che contiene la fusione delle
due collezioni iniziali.
@param: Il riferimento ad un oggetto Involucro
@return: Il riferimento ad un nuovo oggetto Involucro
Il metodo rispetta l'invariante di rappresentazione in quanto ne l'oggetto ricevente, ne il parametro possono essere
null e poichè l'eventuale nuova collezione rispetta la proprietà che Per ogni i, l'i-esima stringa è sempre
contenuta nella (i+1)-esima stringa */

public Involucro2 fondi(Involucro2 coll){

Involucro2 fusione; // Conterrà l'eventuale fusione delle due collezioni
int dimensioneRicevente = collStr.size(); // Contiene la dimensione della collezione del ricevente
int dimensioneParametro = coll.collStr.size(); // Contiene la dimensione della collezione del parametro
int cont;

// Contiene l'ultima stringa della collezione ricevente
String ultimoElemRicevente = (String) collStr.elementAt(dimensioneRicevente);

// Contiene la prima stringa della collezione referenziata dal parametro
String primoElemPar = (String) coll.collStr.elementAt(0);

/* Se la prima stringa della collezione referenziata dal parametro contiene l'ultima stringa della collezione
dell'oggetto ricevente */
if(primoElemPar.contains(ultimoElemRicevente)){
fusione = new Involucro2(); // Costruisci un nuovo oggetto Involucro che conterrà la fusione

// Copia in ordine tutte le stringhe della prima collezione (oggetto ricevente) nell'oggetto fusione
for(cont=0; cont<=dimensioneRicevente; cont++){
fusione.collStr.addElement((String) collStr.elementAt(cont));
}

// Poi copia in ordine tutte le stringhe della collezione referenziata dal parametro nell'oggetto fusione
for(cont=0; cont<=dimensioneRicevente; cont++){
fusione.collStr.addElement((String) coll.collStr.elementAt(cont));
}
}

/* Se invece non è rispettata la prprietà che la prima stringa del parametro contiene l'ultima stringa
della collezione ricevente solleva un'eccezione */
else throw new CollezioneParametroNonValidaExcepion();

// Alla fine, se non è stata sollevata l'eccezione ritorna l'oggetto creato e popolato
return fusione;
}


/* Iteratore */

private class MioIteratore implements Iterator{ // E' la classe interna che implementa l'interfaccia Iterator

public int dove; // Rappresenta la posizione all'interno della collezione su cui si itera

public MioIteratore(){ // Costruttore del generatore
dove = 0; // L'iterazione viene fatta partire dal primo elemento della collezione
}

public Object next(){ // Restituisce l'elemento correte della collezione su cui si stà iterando
return collStr.elementAt(dove);
}

public boolean hasNest(){ // Restituisce true se ci sono ancora elementi su cui iterare, false altrimenti
return dove < collStr.size();
}

public void remove(){ // Passa al prossimo elemento della collezione
dove++;
}
}

public Iterator enumera(){ // Maschero l'implementazione di MioIterator usando un metodo enumera
return new MioIteratore();
}

}


Ho 2 problemi: il primo è che non sòperchè mi dà un errore di compilazione:

C:\Programmi\Crimson Editor\template\esercizi\esami\11-07-07>javac Involucro2.java
Involucro2.java:123: Involucro2.MioIteratore is not abstract and does not override abstract method hasNext() in java.util.
Iterator
private class MioIteratore implements Iterator{ // E' la classe interna che implementa l'interfaccia Itera
tor
^
Note: Involucro2.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error

Da che dipende? Come risolvere?

Poi l'ultimo punto del compito mi chiede:

Si richiede una generalizzazione del tipo Involucro che possa rappresentare e gestire insiemi di oggetti qualsiasi (oltre che di stringhe). Proggettare ed implementare tutte le entità necessarie al conseguimento di tale obbiettivo

Primo dubbio:
Involucro mi rappresentava insiemi di stringhe in cui la i-esima stringa era totalmente contenuta nella (i+1)-esima stringa quindi cose del tipo: {a, ab, cab, cabz}

Qui mi si chiede di generalizzarlo...ma questa proprietà dovrà essere valida anche per la generalizzazione? (Ad esempio una collezione che gestisce rettangoli dove il primo rettangolo è contenuto nel secondo che a sua volta è contenuto nel terzo e così via...)

Tranne che non sò bene come farlo...

1) IDEA 1: Realizzo la classe Involucro2 come una CLASSE ABSTRACT che contiene la rappresentazione della collezione sotto forma di Vector e che contiene l'implementazione del costruttore (che tanto crea una collezione vuota) e dichiaro come metodi abstract i vari metodi inserisci() e fondi() (l'iteratore credo che posso implementarlo direttamente nella classe abstract perchè itero sulla collezione che è rappresentata dal Vector nella classe abstract)

Poi da questa classe abstract estendo i vari tipi di collezioni come appunto Involucro2Stringhe, Involucro2Rettangoli, Involucro2Circonferenze, etcetc

ed in ogni sottoclasse che estende Involucro2 implemento ad hoc i metodi inserisci e fondi in maniera appropriata

2) IDEA 2 (più strampalata): Avevo pensato di creare un'interface chiamata Contenibile:

public interface Contenibile{
double contiene(Contenibile d); // Ogni elemento deve essere capace di dire se è contenuto in un altro elemento
}


Poi nella classe Involucro2 il Vector conterrà collezioni di Contenibili ed il metodo aggiungi e fondi useranno il metodo contiene() di Contenibili per controllare se l'i-esimo elemento è contenuto nell'(i+1)-esimo elemento dellacollezione.

Implemento Contenibile per creare tipi di dato come stringheContenibili, rettangoliContenibili, circonferenzeContenibili, etcetc ed in ognuno di esse implemento il metodo abstrac contiene().

mmm come fare?

Tnx

banryu79
04-06-2009, 11:25
Ho 2 problemi: il primo è che non sòperchè mi dà un errore di compilazione:
C:\Programmi\Crimson Editor\template\esercizi\esami\11-07-07>javac Involucro2.java
Involucro2.java:123: Involucro2.MioIteratore is not abstract and does not override abstract method hasNext() in java.util.
Iterator
private class MioIteratore implements Iterator{ // E' la classe interna che implementa l'interfaccia Itera
tor
^
Note: Involucro2.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error
Da che dipende? Come risolvere?

Dai il giusto nome al metodo che hai chiamato 'hasNest' :D nella classe interna a 'Involucro2' di nome 'MioIteratore' volevi scrivere 'hasNext'.

Scusa la domanda ma scrivi il codice su un normalissimo editor di testo?
Perchè se tu usassi un IDE che esegue il controllo della sintassi al volo ti risparmieresti un po' di tempo per errori banali come questo.

Potresti provare a scaricare Eclipse o NetBeans.
A casa li potresti usare per editare il codice, quando poi compila ed è a posto, lo copi-incolli nell'editor "di ordinanza" che dovete usare a lezione (ti porti dietro i .java).

e-commerce84
04-06-2009, 12:41
Dai il giusto nome al metodo che hai chiamato 'hasNest' :D nella classe interna a 'Involucro2' di nome 'MioIteratore' volevi scrivere 'hasNext'.

Scusa la domanda ma scrivi il codice su un normalissimo editor di testo?
Perchè se tu usassi un IDE che esegue il controllo della sintassi al volo ti risparmieresti un po' di tempo per errori banali come questo.

Potresti provare a scaricare Eclipse o NetBeans.
A casa li potresti usare per editare il codice, quando poi compila ed è a posto, lo copi-incolli nell'editor "di ordinanza" che dovete usare a lezione (ti porti dietro i .java).

La proff ci obliga ad usare un editorino stupidino (si chiama Crimson Editor)...mm si dovrei installarmi un'IDE...lo farò :D

javacomelava
04-06-2009, 14:06
Ciao

la tua è una buona idea,però non capisco perche dichiari DOUBLE il metodo contiente (Contenibile d).... Se ci pensi questo metodo dovrà essere boolean in quando dovrà rispondere alla domanda CONTIENE???

Ti posto il mio codice,avendo già risolto questo "esame":

Edit: codice tolto

Ho tralasciato documetnazione , commenti etc etc... se ti servono fai un fischio.Spero di esserti stato utile.

Ciaooo

cionci
04-06-2009, 14:43
Come specificato nel regolamento di sezione, è vietato risolvere completamente esercizi di esame.

Meglio correggere l'autore del thread, tra l'altro ha già postato una sua versione, che dare una soluzione completa.

javacomelava
04-06-2009, 14:57
scusami cionci....siamo "colleghi" di facoltà,abbiamo entrambi un'esame lunedi...ed io avevo gia svolto questa prova che lui ha postato.Era solo per questo,avevo già letto il regolamento.

In ogni caso lui già ci era arrivato da sè....era solo il TIPO del metodo dell'interface che non era esatto(o meglio....non era vantaggioso...molto piu semplice farlo boolean che double)...detto ciò,se posso riposto la soluzione sennò fa niente ...


saluti :D

e-commerce84
04-06-2009, 16:09
Ciao

la tua è una buona idea,però non capisco perche dichiari DOUBLE il metodo contiente (Contenibile d).... Se ci pensi questo metodo dovrà essere boolean in quando dovrà rispondere alla domanda CONTIENE???

Ti posto il mio codice,avendo già risolto questo "esame":

Edit: codice tolto

Ho tralasciato documetnazione , commenti etc etc... se ti servono fai un fischio.Spero di esserti stato utile.

Ciaooo


Perchè ho fatto copia incolla da un'altra interface che avevo scritto per un altro computo e cambiandogli nome dell'interface e del metodo ma mi ero dimenticato di cambiare il tipo restituito dal metodo che deve essere boolean

cionci
04-06-2009, 16:49
e-commerce84: quindi hai risolto ? In tal caso javacomelava può postare anche al sua soluzione per confronto.

e-commerce84
04-06-2009, 18:59
e-commerce84: quindi hai risolto ? In tal caso javacomelava può postare anche al sua soluzione per confronto.

me lo ha gia passato su msn :-)

Cmq la mia versione ecchila:


import java.util.*;

public class InvolucroGenerico{
/** OVERVIEW: Involucro rappresenta una collezione dinamica di oggetti generici del tipo GenericoContenibile del tipo
<s1, s2, s3,...., sn> tali che s_i è completamente contenuta in s_(i+1).

V = {{s1,s2,s3,...,sn>: Per ogni i s_i è una stringa ed s_i è interamente contenuto in s_(i+1)}}

O = inserisci: Se l'oggetto che si vuole inserire è coerente con la rappresentazione della collezione
(è una stringa) e con lo stato attuale della collezione (i valori già presenti nella
collezione), allora lo inserisce nella collezione modificandola

fondi: Date collezioni S e T se s_n è interamente contenuto in t_1 allora fonde le due collezioni nel
seguente modo: S = <s1,s2,s3,...,sn> T = {t1,t2,t3,...,tn} --> {s1,s2,s3,...,sn,t1,t2,t3,..,tn}

iteratore: itera sullacollezione */

Vector collezione; // Rappresenta la collezione omogenea di oggetti GenericoContenibile

/** COSTRUTTORE:
EFFECTS: Crea un nuovo oggetto di tipo Involucro che rappresenta la collezione vuota
@param: void:
@return: Il riferimento ad un oggetto di tipo Involucro
Il costruttore soddisfa l'invariante di rappresentazione in quanto: 1) Viene assegnata alla variabile di istanza
collStr il riferimento ad un nuovo Vector quindi no è mai null. 2) Il costruttore crea una collezione vuota, quindi
qualsiasi sia il primo elemento va bene */

public InvolucroGenerico(){
collezione = new Vector(); // Crea la collezione vuota assegnando a collezione il riferimento ad un nuovo Vector vuoto
}

/** Metodo inserisci()
EFFECTS: Se il parametro può essere inserito nella collezione (se contiene completamente l'ultima stringa della
collezione, allora viene inserito nella collezione rappresentata dall'oggetto ricevente, altrimenti viene
sollevata una ParametroNonValidoException
MODIFIES: this
@param: Un oggetto di tipo GenericoContenibile
Il metodo inserisci() soddisfa l'invariante di rappresentazione in quanto se la collezione è vuota permette
l'inserimento di un oggetto qualsiasi, se invece nella collezione è già presente qualcosa prima di inserire il
parametro controlla che il parametro contiene completamente l'ultimo oggetto presente nella collezione. Se ciò è
verificato lo inserisce, altrimenti no e la collezione rimane sempre coerente con la sua definizione */

public void inserisci(GenericoContenibile x){

int dimensione = collezione.size() ; // Contiene la dimensione del Vector collezione
GenericoContenibile ultimo = (GenericoContenibile)collezione.elementAt(dimensione); // Ultimo elemento della collezione

if(collezione.size() == 0) // Se la collezione è vuota
collezione.addElement(x); // Aggiunge x alla collezione in prima posizione

else{ // Se invece la collezione non è vuota
/* Controlla se il tipo effettivo del parametro è omogeneo con i tipi effettivi degli elementi contenuti nella
collezione */
if(collezione.elementAt(0).getClass().isInstance(x)){ // Se parametro ed elementi della collezione hanno stesso tipo
if(x.contiene(ultimo)) // Se lo stato del parametro contiene lo stato dell'ultimo elemento della collezione
collezione.addElement(x); // allora aggiungilo alla collezione
else throw new UltimoNonContenutoException(); // altrimenti solleva una UltimoNonContenutoException
}

else // Se invece il parametro non ha lo stesso tipo effettivo degli elementi contenuti nella collezione
throw new ParametroNonValidoException(); // Solleva una ParametroNonValidoException
}
}

/** Metodo fondi():
EFFECTS: Se possibile fonde la collezione ricevente con quella referenziata dal parametro. Tale fusione è possibile
se e solo se l'ultimo elemento della collezione ricevente è totalmente contenuto nel primo elemento della
collezione referenziata dal parametro, altrimenti solleva una CollezioneParametroNonValidaExcepion
Eventualmente la fusione fosse possiebile il metodo crea una nuova collezione che contiene la fusione delle
due collezioni iniziali.
@param: Il riferimento ad un oggetto InvolucroGenerico
@return: Il riferimento ad un nuovo oggetto InvolucroGenerico
Il metodo rispetta l'invariante di rappresentazione in quanto ne l'oggetto ricevente, ne il parametro possono essere
null e poichè l'eventuale nuova collezione rispetta la proprietà che Per ogni i, l'i-esima stringa è sempre
contenuta nella (i+1)-esima stringa */

public InvolucroGenerico fondi(InvolucroGenerico coll){
InvolucroGenerico fusione; // Conterrà l'eventuale fusione delle due collezioni
int dimensioneRicevente = collezione.size(); // Contiene la dimensione della collezione del ricevente
int dimensioneParametro = coll.collezione.size(); // Contiene la dimensione della collezione del parametro
int cont;

// Contiene l'ultimo oggetto della collezione ricevente
GenericoContenibile ultimoElemRicevente = (GenericoContenibile) collezione.elementAt(dimensioneRicevente);

// Contiene il primo oggetto della collezione referenziata dal parametro
GenericoContenibile primoElemPar = (GenericoContenibile) coll.collezione.elementAt(0);

/* Se il primo oggetto della collezione referenziata dal parametro contiene l'ultimo oggetto della collezione
ricevente */
if(primoElemPar.contiene(ultimoElemRicevente)){
fusione = new InvolucroGenerico(); // Costruisci un nuovo oggetto Involucro che conterrà la fusione

// Copia in ordine tutti gli oggetti della prima collezione (oggetto ricevente) nell'oggetto fusione
for(cont=0; cont<=dimensioneRicevente; cont++){
fusione.collezione.addElement((GenericoContenibile) collezione.elementAt(cont));
}

// Poi copia in ordine tutti gli oggetti della collezione referenziata dal parametro nell'oggetto fusione
for(cont=0; cont<=dimensioneRicevente; cont++){
fusione.collezione.addElement((GenericoContenibile) coll.collezione.elementAt(cont));
}
}

/* Se invece non è rispettata la prprietà che il primo oggetto referenziato dal parametro contiene l'ultimo
oggetto della collezione ricevente solleva un'eccezione */
else throw new CollezioneParametroNonValidaExcepion();

// Alla fine, se non è stata sollevata l'eccezione ritorna l'oggetto creato e popolato
return fusione;
}

/* Iteratore */

private class MioIteratore implements Iterator{ // E' la classe interna che implementa l'interfaccia Iterator

public int dove; // Rappresenta la posizione all'interno della collezione su cui si itera

public MioIteratore(){ // Costruttore del generatore
dove = 0; // L'iterazione viene fatta partire dal primo elemento della collezione
}

public Object next(){ // Restituisce l'elemento correte della collezione su cui si stà iterando
return collezione.elementAt(dove);
}

public boolean hasNext(){ // Restituisce true se ci sono ancora elementi su cui iterare, false altrimenti
return dove < collezione.size();
}

public void remove(){ // Passa al prossimo elemento della collezione
dove++;
}
}

public Iterator enumera(){ // Maschero l'implementazione di MioIterator usando un metodo enumera
return new MioIteratore();
}

}


Credo che vada bene :D