Metodologie di Programmazione a.a. 2010-2011

Soluzioni prova intermedia - 3 maggio 2011

Soluzione esercizio [AEKI]
  1. Definizione della classe base e delle sottoclassi.
    /*****************************  FILE: Articolo.java  *****************************/
    public class Articolo {
        public static class Misure {
            public final int altezza, larghezza, profondita;
    
            public Misure(int l, int a, int p) {
                larghezza = l;
                altezza = a;
                profondita = p;
            }
    
            @Override
            public String toString() {
                return "L: "+larghezza+"cm, H: "+altezza+"cm, P: "+profondita+"cm";
            }
        }
        
        private final String codice;
        private Misure misure;
    
        protected Articolo(String c, Misure m) {
            codice = c;
            misure = m;
        }
    
        public String getCodice() { return codice; }
        public Misure getMisure() { return misure; }
        public float getPrezzo() { return 0; }
    
        @Override
        public boolean equals(Object o) {
            if (o == null) return false;
            else if (o instanceof Articolo) {
                Articolo a = (Articolo)o;
                return codice.equals(a.codice);
            } else
                return false;
        }
    }
    
    /*****************************  FILE: Mobile.java  *****************************/
    import java.util.Arrays;
    
    public class Mobile extends Articolo {
        private final String categoria;
        private float prezzo;
        private String[] colori = new String[0];
    
        public Mobile(String c, Misure m, String cat, float p) {
            super(c, m);
            categoria = cat;
            prezzo = p;
        }
    
        public void setPrezzo(float p) { prezzo = p; }
    
        @Override
        public float getPrezzo() { return prezzo; }
    
        public boolean addColore(String c) {
            if (c == null)
                throw new NullPointerException();
            int nc = colori.length;
            for (int i = 0 ; i < nc ; i++)
                if (colori[i].equals(c)) return false;
            colori = Arrays.copyOf(colori, nc + 1);
            colori[nc] = c;
            return true;
        }
    
        public String[] getColori() { return colori.clone(); }
        public String getCategoria() { return categoria; }
    
        @Override
        public String toString() {
            String str = categoria+" "+getCodice()+" "+getMisure();
            if (colori.length > 0) {
                str += "\nColori:";
                for (int i = 0 ; i < colori.length ; i++)
                    str += " "+colori[i];
            }
            return str+"\nPrezzo: "+getPrezzo();
        }
    }
    
    /*****************************  FILE: Comb.java  *****************************/
    import java.util.Arrays;
    
    public class Comb extends Articolo {
        private int sconto = 0;
        private Mobile[] componenti = new Mobile[0];    //I mobili componenti distinti
        private int[] quant = new int[0];               //Per ogni componente la quantità
    
        public Comb(String c, Misure m) {
            super(c, m);
        }
    
        public void setSconto(int s) {
            if (s < 0 || s > 100) throw new IllegalArgumentException();
            sconto = s;
        }
    
        @Override
        public float getPrezzo() {
            float p = 0;
            for (int i = 0 ; i < componenti.length ; i++)
                p += componenti[i].getPrezzo()*quant[i];
            return p*((100 - sconto)/100f);
        }
    
        public void addMobile(Mobile m) {
            if (m == null) throw new NullPointerException();
            int nc = componenti.length;
            for (int i = 0 ; i < nc ; i++)
                if (componenti[i].equals(m)) {
                    quant[i]++;
                    return;
                }
            componenti = Arrays.copyOf(componenti, nc + 1);
            quant = Arrays.copyOf(quant, nc + 1);
            componenti[nc] = m;
            quant[nc] = 1;
        }
    
        public int contains(Mobile m) {
            for (int i = 0 ; i < componenti.length ; i++)
                if (componenti[i].equals(m)) return quant[i];
            return 0;
        }
    
        @Override
        public String toString() {
            String str = "Combinazione "+getCodice()+" "+getMisure();
            for (int i = 0 ; i < componenti.length ; i++) {
                Mobile m = componenti[i];
                str += "\n"+quant[i]+" "+m.getCategoria()+" "+m.getCodice()+" "+m.getMisure();
            }
            return str + "\nPrezzo: "+getPrezzo();
        }
    }
    
  2. Il metodo statico trova() della classe Articolo.
       public static Comb[] trova(Articolo[] art, Mobile m, float max) {
            Comb[] trovati = new Comb[0];
            for (int i = 0 ; i < art.length ; i++) {
                if (art[i] instanceof Comb && art[i].getPrezzo() <= max) {
                    Comb c = (Comb)art[i];
                    if (c.contains(m) > 0) {
                        int n = trovati.length;
                        trovati = Arrays.copyOf(trovati, n + 1);
                        trovati[n] = c;
                    }
                }
            }
            return trovati;
        }
    
Soluzione esercizio [Errori]
Ci sono quattro errori.
  1. La linea int n = sA[0].length(); provoca un errore in esecuzione perché sA[0] ha valore null, con conseguente lancio di una NullPointerException.
  2. La linea n = oA[0][0]; produce un errore in compilazione dovuto al fatto che l'espressione oA[0] non è di tipo array (è di tipo Object).
  3. La linea oA[0] = new long[5]; provoca un errore in esecuzione con lancio di una ArrayStoreException perché oA contiene il riferimento ad un array di array di int e un array di int non è un supertipo di array di long.
  4. La linea System.out.print(o.length()); produce un errore in compilazione dovuto al fatto che il tipo della variabile o è Object e tale classe non ha il metodo length().

Soluzione esercizio [GeoMap]
  1. La classe GeoMap.
    public class GeoMap {
        public static class Entity {
            public final int codice;
            public final String tipo, nome;
    
            public Entity(int c, String t, String n) {
                codice = c;
                tipo = t;
                nome = n;
            }
    
            @Override
            public boolean equals(Object o) {
                if (o == null) return false;
                else if (o instanceof Entity) {
                    Entity e = (Entity)o;
                    return codice == e.codice;
                } else return false;
            }
        }
    
        private final Entity[][] mappa;
        private final int nr, nc;
    
        public GeoMap(int nr, int nc) {
            mappa = new Entity[nr][nc];
            this.nr = nr;
            this.nc = nc;
        }
    
        public void set(int r, int c, Entity g) {
            if (r < 0 || r >= nr || c < 0 || c >= nc)
                throw new IllegalArgumentException();
            mappa[r][c] = g;
        }
    
        public void print(int r, int c, int n) {
            if (n < 0 || r < 0 || r + n > nr || c < 0 || c + n > nc)
                throw new IllegalArgumentException();
            for (int i = r ; i < r + n ; i++) {
                for (int j = c ; j < c + n ; j++) {
                    Entity g = mappa[i][j];
                    System.out.print(g != null ? g.nome.charAt(0) : '.');
                }
                System.out.println();
            }
        }
    }
    
  2. Definizione del metodo count() della classe GeoMap:
    import java.util.Arrays;
    
        public int count(String t) {
            Entity[] found = new Entity[0];
            for (int i = 0 ; i < nr ; i++)
                for (int j = 0 ; j < nc ; j++) {
                    Entity g = mappa[i][j];
                    if (g != null && g.tipo.equals(t)) {
                        int n = found.length, k = 0;
                        while (k < n && !found[k].equals(g))
                            k++;
                        if (k == n) {
                            found = Arrays.copyOf(found, n + 1);
                            found[n] = g;
                        }
                    }
                }
            return found.length;
        }
    
  3. Definizione del costruttore aggiuntivo della classe GeoMap:
    import java.io.*;
    import java.util.*;
    
        public GeoMap(String pathname) throws FileNotFoundException {
            Scanner scan = new Scanner(new File(pathname));
            nr = scan.nextInt();
            nc = scan.nextInt();
            mappa = new Entity[nr][nc];
            while (scan.hasNextInt()) {
                int codice = scan.nextInt();
                String tipo = scan.next();
                String nome = scan.next();
                int i = scan.nextInt();
                int j = scan.nextInt();
                mappa[i][j] = new Entity(codice, tipo, nome);
            }
            scan.close();
        }