Metodologie di Programmazione a.a. 2010-2011

Soluzioni prova scritta 19 luglio 2011


Soluzione esercizio [Ateneo]
  1. Definizione delle classi.
    FILE: Corso.java
    public class Corso {
        public final String codice;
        public final String nome;
        
        public Corso(String c, String n) {
            codice = c;
            nome = n;
        }
        
        @Override
        public boolean equals(Object o) {
            if (o == null || !(o instanceof Corso)) return false;
            else return ((Corso)o).codice.equals(codice);
        }
        
        @Override
        public String toString() {
            return codice+" "+nome;
        }
    }
    
    FILE: Persona.java
    public class Persona {
        private String nome, cognome;
        
        public Persona(String n, String c) {
            nome = n;
            cognome = c;
        }
        
        public String getNome() { return nome; }
        public String getCognome() { return cognome; }
        
        @Override
        public String toString() {
            return "Nome: "+nome+"  "+"Cognome: "+cognome;
        }
    }
    
    FILE: Studente.java
    import java.util.Arrays;
    
    public class Studente extends Persona {
        private static class Esame {
            public final Corso corso;
            public final String data;
            public final int voto;
            
            public Esame(Corso c, String d, int v) {
                corso = c;
                data = d;
                voto = v;
            }
            
            @Override
            public String toString() {
                return corso+" "+data+" "+voto;
            }
        }
        
        private String matricola;
        private Esame[] esami = new Esame[0];
        
        public Studente(String n, String c, String m) {
            super(n, c);
            matricola = m;
        }
        
        public void setMatricola(String m) { matricola = m; }
        public String getMatricola() { return matricola; }
        
        public boolean add(Corso c, String d, int v) {
            if (c == null || d == null || v < 18 || v > 31)
                throw new IllegalArgumentException();
            int n = esami.length;
            for (int i = 0 ; i < n ; i++)
                if (esami[i].corso.equals(c))
                    return false;
            esami = Arrays.copyOf(esami, n + 1);
            esami[n] = new Esame(c, d, v);
            return true;
        }
        
        @Override
        public String toString() {
            String str = super.toString();
            str += "  STUDENTE "+matricola;
            for (int i = 0 ; i < esami.length ; i++)
                str += "\n"+esami[i];
            return str;
        }
    }
    
    FILE: Docente.java
    import java.util.Arrays;
    
    public class Docente extends Persona {
        private Corso[] corsi = new Corso[0];
        
        public Docente(String n, String c) {
            super(n, c);
        }
        
        public boolean add(Corso c) {
            if (c == null) throw new NullPointerException();
            int n = corsi.length;
            for (int i = 0 ; i < n ; i++)
                if (corsi[i].equals(c))
                    return false;
            corsi = Arrays.copyOf(corsi, n + 1);
            corsi[n] = c;
            return true;
        }
        
        public boolean remove(Corso c) {
            int i = 0, n = corsi.length;
            while (i < n && !corsi[i].equals(c))
                i++;
            if (i < n) {
                corsi[i] = corsi[n - 1];
                corsi = Arrays.copyOf(corsi, n - 1);
                return true;
            } else
                return false;
        }
        
        public Corso[] getCorsi() { return corsi.clone(); }
        
        @Override
        public String toString() {
            String str = super.toString();
            str += "  DOCENTE";
            for (int i = 0 ; i < corsi.length ; i++)
                str += "\n"+corsi[i];
            return str;
        }
    }
    
  2. Il metodo statico da aggiungere alla classe Persona.
        //Metodo ausiliario che ritorna true se c è presente nell'array corsi
        private static boolean ispresent(Corso[] corsi, Corso c) {
            for (int i = 0 ; i < corsi.length ; i++)
                if (corsi[i].equals(c))
                    return true;
            return false;
        }
        
        public static Corso[] insegnati(Persona[] p) {
            Corso[] corsi = new Corso[0];
            for (int i = 0 ; i < p.length ; i++) {
                if (p[i] instanceof Docente) {
                    Corso[] c = ((Docente)p[i]).getCorsi();
                    for (int j = 0 ; j < c.length ; j++)
                        if (!ispresent(corsi, c[j])) {
                            corsi = Arrays.copyOf(corsi, corsi.length + 1);
                            corsi[corsi.length - 1] = c[j];
                        }
                }
            }
            return corsi;
        }
    
SECONDA PARTE

Soluzione esercizio [Dynamic Tree]
import java.util.*;

public class DTree<V> implements Iterable<V> {
    private final Generator<V> gen;
    private final Map<V, Set<V>> children = new HashMap<V, Set<V>>();
    private final Map<V, V> parent = new HashMap<V, V>();
    
    public DTree(Generator<V> g, V root) {
        if (g == null || root == null) throw new NullPointerException();
        gen = g;
        parent.put(root, null);
    }
    
    public boolean isExpanded(V val) {
        return children.containsKey(val);
    }
    
    public Set<V> children(V val) {
        if (!parent.containsKey(val))
            throw new IllegalArgumentException();
        if (!isExpanded(val)) {
            Set<V> cset = gen.generate(val);
            for (Iterator<V> iter = cset.iterator() ; iter.hasNext() ; ) {
                V x = iter.next();
                if (parent.containsKey(x))
                    iter.remove();
                else 
                    parent.put(val, x);
            }
            children.put(val, cset);
        }
        return new HashSet(children.get(val));
    }
    
    public List<V> path(V val) {
        if (!parent.containsKey(val))
            throw new IllegalArgumentException();
        List<V> p = new ArrayList<V>();
        while (val != null) {
            p.add(val);
            val = parent.get(val);
        }
        return p;
    }
    
    public int height(V val) {
         if (!parent.containsKey(val))
            throw new IllegalArgumentException();
         int h = 1;
         if (children.containsKey(val)) {
             int max = 0;
             for (V x : children.get(val)) {
                 int hx = height(x);
                 if (hx > max) max = hx;
             }
             h += max;
         }
         return h;
    }
    
    public Iterator<V> iterator() {
        return Collections.unmodifiableSet(parent.keySet()).iterator();
    }
}

Soluzione esercizio [Errori]
Ci sono quattro errori.
  1. Linea 8: Integer n = extL.get(0);   provoca un errore in compilazione dovuto al fatto che il metodo get() di extL ritorna un qualsiasi tipo che è un sottotipo di Number e quindi non è garantito essere un sottotipo di Integer.
  2. Linea 10: array[0][0] = extL.get(0).toString();   provoca un errore in esecuzione, con lancio di NullPointerException, dovuto la fatto che array[0] non è stato inizializzato e quindi è null.
  3. Linea 11: extL.add(new Double(0.5));   provoca un errore in compilazione dovuto al fatto che il tipo degli elementi di extL può essere un qualsiasi sottotipo di Number e quindi Double non è garantito essere un sottotipo del tipo degli elementi.
  4. Linea 13: array[0][1] = extL.get(1).toString();   provoca un errore in esecuzione, con lancio di IndexOutOfBoundsException, dovuto al tentativo di accedere tramite get ad un elemento oltre la lunghezza della lista.

Soluzione esercizio [Inverse]
import java.util.*;

public class Test {
    public static <K, V> Map<V, Set<K>> invert(Map<K, V> map) {
        Map<V, Set<K>> invmap = new HashMap<V, Set<K>>();
        for (K key : map.keySet()) {
            V val = map.get(key);
            if (!invmap.containsKey(val))
                invmap.put(val, new HashSet<K>());
            invmap.get(val).add(key);
        }
        return invmap;
    }
}