Metodologie di Programmazione a.a. 2010-2011

Soluzioni prova scritta 27 giugno 2011


Soluzione esercizio [SSS]
  1. Definizione delle classi.
    FILE: Data.java
    public class Data {
        public final int g, m, a;
        
        public Data(int g, int m, int a) {
            this.g = g;
            this.m = m;
            this.a = a;
        }
        
            //Ritorna true se d è uguale o antecedente a questa data
        public boolean antecedente(Data d) {
            return d.a < a || (d.a == a && d.m < m) || (d.a == a && d.m == m && d.g <= g);
        }
    }
    
    FILE: Progetto.java
    public class Progetto {
        public final String codice;
        public final Data consegna;
        
        public Progetto(String cod, Data cons) {
            if (cod == null || cons == null)
                throw new NullPointerException();
            codice = cod;
            consegna = cons;
        }
        
        @Override
        public boolean equals(Object o) {
            if (o == null) return false;
            else if (o instanceof Progetto)
                return codice.equals(((Progetto)o).codice);
            else
                return false;
        }
    }
    
    FILE: Dipendente.java
    import java.util.Arrays;
    
    public class Dipendente {
        private String nomCog;
        private float stipBase = 0;
        
        public Dipendente(String nc) {
            nomCog = nc;
        }
        
        public void setStipBase(float sb) { stipBase = sb; }
        
        public float stipendio() { return stipBase; }
    }
    
    FILE: Programmatore.java
    public class Programmatore extends Dipendente {
        private Progetto prog;
        
        public Programmatore(String nc) {
            super(nc);
        }
        
        public void setProgetto(Progetto p) { prog = p; }
        
        public Progetto getProgetto() { return prog; }
        
        @Override
        public float stipendio() {
            float stip = super.stipendio();
            if (prog != null) stip += 0.1f*stip;
            return stip;
        }
    }
    
    FILE: Supervisore.java
    import java.util.Arrays;
    
    public class Supervisore extends Dipendente {
        private Progetto[] progetti = new Progetto[0];
        
        public Supervisore(String nc) {
            super(nc);
        }
        
        public boolean add(Progetto p) {
            if (p == null) return false;
            int n = progetti.length;
            for (int i = 0 ; i < n ; i++)
                if (progetti[i].equals(p)) return false;
            progetti = Arrays.copyOf(progetti, n + 1);
            progetti[n] = p;
            return true;
        }
        
        public boolean remove(Progetto p) {
            int n = progetti.length;
            for (int i = 0 ; i < n ; i++)
                if (progetti[i].equals(p)) {
                    progetti[i] = progetti[n - 1];
                    progetti = Arrays.copyOf(progetti, n - 1);
                    return true;
                }
            return false;
        }
        
        public Progetto[] resp(Data d) {
            Progetto[] p = new Progetto[0];
            for (int i = 0 ; i < progetti.length ; i++) {
                if (d.antecedente(progetti[i].consegna)) {
                    p = Arrays.copyOf(p, p.length + 1);
                    p[p.length - 1] = progetti[i];
                }
            }
            return p;
        }
        
        @Override
        public float stipendio() {
            float stip = super.stipendio();
            return stip + progetti.length*0.1f*stip;
        }
    }
    
  2. Il metodo statico impegnati della classe Dipendente.
    public static Dipendente[] impegnati(Dipendente[] dip, Data d) {
            Dipendente[] imp = new Dipendente[0];
            if (dip == null || d == null) return imp;
            for (int i = 0 ; i < dip.length ; i++) {
                Dipendente dimp = null;
                if (dip[i] instanceof Programmatore) {
                    Progetto p = ((Programmatore)dip[i]).getProgetto();
                    if (p != null && d.antecedente(p.consegna))
                        dimp = dip[i];
                } else if (dip[i] instanceof Supervisore) {
                    Progetto[] p = ((Supervisore)dip[i]).resp(d);
                    if (p.length > 0) dimp = dip[i];
                }
                if (dimp != null) {
                    imp = Arrays.copyOf(imp, imp.length + 1);
                    imp[imp.length - 1] = dimp;
                }
            }
            return imp;
        }
    
SECONDA PARTE

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

public class GeoSet<E extends Geo> implements Iterable<E> {
    private Set<E> set = new HashSet<E>();
    
    public boolean add(E g) {
        if (g == null) return false;
        else return set.add(g);
    }
    
    public boolean remove(E g) {
        return set.remove(g);
    }
    
    public boolean contains(E g) {
        return set.contains(g);
    }
    
    public Set<E> partiallyContained(E g) {
        if (g == null) throw new NullPointerException();
        Set<E> pc = new HashSet<E>();
        for (E e : set) 
            if (!e.disjoint(g) && !e.contained(g))
                pc.add(e);
        return pc;
    }
    
    public <T extends Geo> Map<E, Set<T>> mapC(GeoSet<T> gs) {
        if (gs == null) throw new NullPointerException();
        Map<E, Set<T>> map = new HashMap<E, Set<T>>();
        for (E g : set) {
            Set<T> cs = new HashSet<T>();
            map.put(g, cs);
            for (T e : gs) 
                if (g.contained(e))
                    cs.add(e);
        }
        return map;
    }
    
    public List<E> include(E g, String cat) {
        if (g == null || cat == null) throw new NullPointerException();
        List<E> list = new ArrayList<E>();
        for (E e : set) {
            if (e.getCategory().equals(cat))
                if (g.contained(e)) {
                    int i = 0;
                    while (i < list.size() && list.get(i).contained(e)) 
                        i++;
                    list.add(i, e);
                }
        }
        return list;
    }
    
    public Iterator<E> iterator() {
        return set.iterator();
    }
}

Soluzione esercizio [Errori]
Ci sono tre errori.
  1. Linea 13: copy(intA, nL);   provoca un errore in esecuzione perchè il primo elemento della lista nL è di tipo Double e il metodo copy tenta di assegnarlo a una componente di un array di Integer (lancia ArrayStoreException).
  2. Linea 15: copy(objA, nL);   provoca un errore in compilazione perché Object non è un sottotipo di Number.
  3. Linea 20: nL.remove(n);   provoca un errore in esecuzione con lancio di ConcurrentModificationException dovuto alla modifica della lista mentre era attivo un iteratore sulla lista stessa (in realtà l'errore accade nella linea 18).

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

public class Test {
    public static <T extends Comparable<? super T>> List<T> merge(List<? extends T> a, List<? extends T> b) {
        List<T> mL = new ArrayList<T>();
        int i = 0, j = 0;
        while (i < a.size() || j < b.size()) {
            if (i < a.size() && !(j < b.size() && b.get(j).compareTo(a.get(i)) < 0)) {
                mL.add(a.get(i));
                i++;
            } else {
                mL.add(b.get(j));
                j++;
            }
        }
        return mL;
    }
}