Metodologie di Programmazione a.a. 2009-2010 (canali A-D ed  E-O)

Prova intermedia - 27 aprile 2010

Soluzione esercizio [Azienda]  
  1. Definizione della classe Commessa, della classe Dipendente e delle sue sottoclassi:
    /*****************************  FILE: Commessa.java  *****************************/
    public class Commessa {
    public final String codice;
    public final float incentivo;

    public Commessa(String c, float i) {
    codice = c;
    incentivo = i;
    }
    //Ridefinisce il metodo di Object public boolean equals(Object o) {
    return codice.equals(o);
    }
    }
    /***************************** FILE: Dipendente.java *****************************/ public class Dipendente {
    private String nomeCognome;
    private float stipendioBase;
    private float addizionale;

    public Dipendente(String nomCog, float sb) {
    nomeCognome = nomCog;
    stipendioBase = sb;
    addizionale = 0;
    }

    public String getNomeCognome() { return nomeCognome; }
    public void setNomeCognome(String nc) { nomeCognome = nc; }
    public float getStipendioBase() { return stipendioBase; }
    public void setStipendioBase(float sb) { stipendioBase = sb; }
    public float getAddizionale() { return addizionale; }
    public void setAddizionale(float add) { addizionale = add; }

    public float stipendio() {
    return stipendioBase + addizionale;
    }
    }
    /***************************** FILE: Operaio.java *****************************/ public class Operaio extends Dipendente {
    private Commessa comm;

    public Operaio(String nomCog, float sb) {
    super(nomCog, sb);
    }

    public void setCommessa(Commessa c) { comm = c; }
    public Commessa getCommessa() { return comm; }
    }
    /***************************** FILE: Commerciale.java *****************************/ public class Commerciale extends Dipendente {
    private float totaleComm = 0;

    public Commerciale(String nomCog, float sb) {
    super(nomCog, sb);
    }

    public void addImporto(float imp) {
    totaleComm += imp;
    }

    public void azzeraTotale() { totaleComm = 0; }
    //Ridefinisce il metodo della superclasse
    public float stipendio() {
    return super.stipendio() + (3f/100f)*totaleComm;
    }
    }
    /***************************** FILE: Responsabile.java *****************************/ public class Responsabile extends Dipendente {
    private Commessa[] commesse;

    public Responsabile(String nomCog, float sb) {
    super(nomCog, sb);
    commesse = new Commessa[0];
    }

    public void addCommessa(Commessa c) {
    for (int i = 0 ; i < commesse.length ; i++) //Controlla se c è già presente if (commesse[i].equals(c)) return; //nell'array delle commesse. int nc = commesse.length; //Se non è già presente Commessa[] newArray = new Commessa[nc + 1]; //Crea un nuovo array per contenere anche c for (int i = 0 ; i < nc ; i++) //Copia le vecchie commesse nel nuovo array newArray[i] = commesse[i]; newArray[nc] = c; //Aggiungi c al nuovo array commesse = newArray; //Aggiorna l'array delle commesse } public void removeCommessa(Commessa c) {
    int i = 0, nc = commesse.length; //Trova, se esiste, l'indice dell'array while (i < nc && !commesse[i].equals(c)) i++; //in cui c'è la commessa c. if (i == nc) return; //Se non c'è, esci commesse[i] = commesse[nc - 1]; //altrimenti elimina la commessa c. Commessa[] newArray = new Commessa[nc - 1]; //Crea un nuovo array "ristretto" for (i = 0 ; i < nc - 1 ; i++) //Copia nel nuovo array le commesse newArray[i] = commesse[i]; commesse = newArray; //Aggiorna l'array delle commesse } public boolean isResp(Commessa c) {
    for (int i = 0 ; i < commesse.length ; i++)
    if (commesse[i].equals(c)) return true;
    return false;
    }
    //Ridefinisce il metodo della superclasse public float stipendio() {
    float inc = 0; //Calcola il totale degli incentivi relativi for (int i = 0 ; i < commesse.length ; i++) //a tutte le commesse. inc += commesse[i].incentivo; return super.stipendio() + inc;
    }
    }
  2. Definizione del metodo disimpegna.
            //Metodo ausiliario che se d è un operaio impegnato sulla commessa c, ritorna d come operaio
        private static Operaio impOperaio(Dipendente d, Commessa c) {  //atrimenti ritorna null.
            if (!(d instanceof Operaio)) return null;
    Commessa comOp = ((Operaio)d).getCommessa();
    if (comOp == null) return null;
    return (comOp.equals(c) ? (Operaio)d : null);
    }
    //Metodo ausiliario che se d è un responsabile impegnato sulla commessa c, ritorna d come responsabile private static Responsabile impResponsabile(Dipendente d, Commessa c) { //altrimenti ritorna null. if (!(d instanceof Responsabile)) return null;
    return (((Responsabile)d).isResp(c) ? (Responsabile)d : null);
    }

    public static Dipendente[] disimpegna(Dipendente[] dip, Commessa c) {
    int ni = 0; //Calcola il numero dei dipendenti impegnati sulla commessa c for (int i = 0 ; i < dip.length ; i++) {
    if (impOperaio(dip[i], c) != null || impResponsabile(dip[i], c) != null)
    ni++;
    }
    Dipendente[] imp = new Dipendente[ni]; //L'array che conterrà i dipendenti impegnati su c int j = 0;
    for (int i = 0 ; i < dip.length ; i++) {
    Operaio op = impOperaio(dip[i], c);
    if (op != null) { //Se è un operaio impegnato su c, op.setCommessa(null); //disimpegnalo da c imp[j++] = op; //e aggungilo all'array. } else {
    Responsabile resp = impResponsabile(dip[i], c);
    if (resp != null) { //Se è un responsabile impegnato su c, resp.removeCommessa(c); //disimpegnalo da c imp[j++] = resp; //e aggiungilo all'array. } } } return imp;
    }

Soluzione esercizio [Errori]   Ci sono quattro errori.
  1. Nel costruttore della classe DoubleLine la linea line = l; provoca un errore in compilazione perché dovrebbe essere sostituita da super(l);.
  2. La ridefinizione del metodo print() nella classe DoubleLine è un metodo ricorsivo che se eseguito porta ad un loop infinito. L'invocazione ricorsiva dovrebbe essere sostituita dall'invocazione del metodo della superclasse super.print().
  3. La linea linee[0] = new Line("prima"); provoca un errore in esecuzione (ArrayStoreException) perché l'array contenuto nella variabile linee è un array di DoubleLine e quest'ultimo tipo non è un supertipo di Line.
  4. La linea linee[2].print(); provoca un errore in esecuzione (NullPointerException) perché line[2] ha valore null e si tenta quindi di invocare il metodo print() su un riferimento inesistente.

Soluzione esercizio [Prefix_free]  
  1. La classe PrefixFree con il metodo add.
    public class PrefixFree {
    private String[] set;

    public PrefixFree() {
    set = new String[0];
    }
    //Metodo ausiliario che ritorna true se s1 è un prefisso di s2 private static boolean isPrefix(String s1, String s2) {
    if (s1.length() > s2.length()) return false;
    for (int i = 0 ; i < s1.length() ; i++)
    if (s1.charAt(i) != s2.charAt(i)) return false;
    return true;
    }

    public boolean add(String s) {
    int n = set.length; //Controlla se la stringa s è in relazione for (int i = 0 ; i < n ; i++) //di prefisso con qualche stringa dell'insieme. if (isPrefix(set[i], s) || isPrefix(s, set[i]))
    return false;
    String[] newArray = new String[n + 1]; //Crea un nuovo array per contenere anche s for (int i = 0 ; i < n ; i++) //Copia le vecchie stringhe nel nuovo array newArray[i] = set[i]; newArray[n] = s; //Aggiungi la stringa s set = newArray; return true;
    }
    }
  2. Definizione del metodo extensions() della classe PrefixFree:
        public String[] extensions(String p) {
    int ne = 0; //Conta il numero di stringhe nell'insieme for (int i = 0 ; i < set.length ; i++) //tali che p è un loro prefisso. if (isPrefix(p, set[i])) ne++;
    String[] ext = new String[ne]; //Crea un array per contenere tali stringhe int j = 0;
    for (int i = 0 ; i < set.length ; i++) //Aggiungi le stringhe nell'array if (isPrefix(p, set[i]))
    ext[j++] = set[i];
    return ext;
    }
  3. Il programma è scritto come main della classe PrefixFree.
    import java.io.*;
    import java.util.*;

    public static void main(String[] args) throws FileNotFoundException {
    String inpath = args[0];
    String outpath = args[1];
    String p = args[2];
    File infile = new File(inpath);
    Scanner in = new Scanner(infile); //Apri il file di input in lettura PrefixFree set = new PrefixFree(); //Crea un insieme prefix free vuoto while (in.hasNextLine()) //Aggiungi le linee del file all'insieme if (!set.add(in.nextLine())) { //Se non sono un insieme prefix free System.out.println("Non è prefix free"); //termina il programma. return;
    }
    File outfile = new File(outpath);
    PrintStream out = new PrintStream(outfile); //Apri il file di output in scrittura String[] ext = set.extensions(p); //Ottieni le estensioni della stringa p for (int i = 0 ; i < ext.length ; i++) //Scrivi le estensioni nel file out.println(ext[i]); }