Metodologie di Programmazione a.a. 2010-2011
Prova scritta - 19 luglio 2011
Avvertenze     Le soluzioni devono essere scritte in modo chiaro e ordinato; il codice deve essere indentato per facilitarne la lettura. Si possono consultare libri e appunti ma non è permesso usare computer. Il voto (in trentesimi) sarà determinato dalla somma dei punteggi ottenuti nei vari esercizi.
Chi fa solamente la Seconda Parte: i punti degli esercizi sono da intendersi raddoppiati.
Chi fa l'intero scritto: per raggiungere la sufficienza deve ottenere almeno 8 punti sull'esercizio Ateneo e almeno 10 punti sulla Seconda Parte.


[Ateneo]   Definire una piccola gerarchia di classi per gestire l'archivio di un ateneo (corsi, studenti, docenti).
  1. (max 13 punti)  Definire una classe Corso, immutabile, che mantiene il codice (stringa) e il nome (stringa) di un corso e ridefinisce il metodo equals (due corsi sono uguali se hanno lo stesso codice).
         Definire la classe base Persona che mantiene il nome e il cognome (due stringhe). Il costruttore prende in input questi due parametri e la classe ha metodi per leggerli.
         Definire la sottoclasse Studente che mantiene la matricola (stringa) e l'elenco degli esami sostenuti. Ogni esame consiste di un corso (di tipo Corso), una data (stringa) e un voto (intero). Il costruttore prende in input anche la matricola e la classe ha metodi per leggerla e scriverla. Definire un metodo boolean add(Corso c, String d, int v) che aggiunge all'elenco un nuovo esame sostenuto solo se non c'è già un esame relativo allo stesso corso: se uno dei parametri è null o v < 18 o v > 31, lancia IllegalArgumentException. La classe ridefinisce il metodo toString, vedi l'esempio più avanti.
         Definire la sottoclasse Docente che mantiene l'elenco dei corsi insegnati. La classe ha metodi per aggiungere (se non già presente) e rimuovere un corso dall'elenco. Definire anche un metodo che ritorna in un array ex novo l'elenco dei corsi. La classe ridefinisce il metodo toString, vedi l'esempio qui sotto.
         Esempio di stringhe ritornate dai metodi toString delle classi Studente e Docente, rispettivamente:
    "Nome: Maria  Cognome: Rossi  STUDENTE 12345678
    1000567 Fondamenti di Programmazione 1/2/2010 30
    1000678 Metodologie di Programmazione 12/9/2010 28"
    
    "Nome: Luisa  Cognome: Verdi  DOCENTE
    1000567 Fondamenti di Programmazione"
    
  2. (max 5 punti)  Aggiungere alla classe Persona un metodo statico che preso in input un array di Persona ritorna un array contenente tutti i corsi (senza ripetizioni) insegnati dai docenti presenti nell'array di input.
SECONDA PARTE
[Dynamic Tree] (max 14 punti)   Si vuole definire una classe per gestire alberi dinamici con valori di tipo parametrico V associati ai nodi. Gli alberi sono dinamici nel senso che i figli di un nodo sono generati "on demand", cioè, quando sono richiesti per la prima volta. Un albero dinamico è costruito fornendo la radice (un valore di tipo V) e un generatore che è un oggetto che implementa l'iterfaccia:
import java.util.Set;

public interface Generator<V> {
    //Ritorna l'insieme (possibilmente vuoto) dei valori generati dal valore x
    Set<V> generate(V x);
}
I figli di un nodo con valore val corrispondono ai valori ritornati dal metodo generate(val) che non erano presenti nell'albero al momento in cui i figli sono stati richiesti la prima volta. Un nodo i cui figli sono stati già generati si dice espanso. Ad esempio, supponiamo che il tipo V è String e il generatore per ogni stringa x genera l'insieme di tutte le parole italiane che si ottengono da x sostituendo uno dei caratteri di x. Se l'albero è creato con la radice "giallo", dopo tre espansioni potrebbe avere la seguente forma:
              giallo 1 {piallo, gialli, gialle, gialla}         
    ______________________________|______________________________   
   |        |                         |                          |  
piallo   gialli   gialle 2 {gialli, pialle, gialla, giallo}   gialla
                                      |                                                               
                      pialle 3 {piallo, gialle, pialla}                 
                                      |                                                                                
                                   pialla                                                                                                                                   
A destra di ogni nodo espanso è indicato (in grigio) il numero d'ordine dell'espansione e l'insieme dei valori prodotti dal generatore. Chiaramente, la forma dell'albero dipende da quali nodi sono stati espansi e dall'ordine in cui sono stati espansi.
Definire una classe DTree per gestire alberi dinamici con valori di tipo parametrico V con i seguenti costruttori e metodi. I tre metodi children, path e height, se val non appartiene all'albero, lanciano IllegalArgumentException. La classe deve implementare Iterable per iterare sui valori dell'albero e l'iteratore non deve permettere la rimozione.

[Errori] (max 4 punti)   Il seguente codice Java contiene uno o più errori. Trovare gli errori, spiegarli e dire per ognuno se si verifica in compilazione o in esecuzione.
 1 import java.util.*;
 2 
 3 public class Test {
 4     public static void main(String[] args) {
 5         List<Number> list = new ArrayList<Number>();
 6         list.add(13);
 7         List<? extends Number> extL = list;
 8         Integer n = extL.get(0);
 9         String[][] array = new String[10][];
10         array[0][0] = extL.get(0).toString();
11         extL.add(new Double(0.5));
12         array[0] = new String[20];
13         array[0][1] = extL.get(1).toString();
14         list.add(0.78);
15     }
16 }

[Inverse] (max 4 punti)   Definire un metodo statico generico che prende in input una mappa map (di tipo Map<K,V>) e ritorna la mappa inversa. Cioè, la mappa che associa ad ogni valore v di map l'insieme delle chiavi k tali che v è il valore associato a k.