Il file sorgente TestRational.java definisce una classe (che usa la classe Rational e la classe AConsoleReader) che legge due numeri razional da terminale, legge quale tra le 4 operazioni deve essere effettuata, e scrive su terminale il risultato dell'operazione sui numeri letti.
Il file sorgente Rational.java contiene uno "scheletro" della classe Rational, in cui i metodi numerator() e denominator() restituiscono la stringa "1". Tale file puo' essere usato per compilare ed eseguire TestRational.java PRIMA di aver completato la scrittura della classe Rational.
Il file sorgente MathUtil.java contiene metodi per il calcolo del MCD di due int e di due BigInteger.
Il file sorgente Rational.java contiene una implementazione della classe Rational che utilizza degli int per rappresentare numeratore e denominatore.
Il file sorgente Rational.java contiene una implementazione della classe Rational che utilizza dei BigInteger per rappresentare numeratore e denominatore.
Questa soluzione usa il metodo:
/* AI: a != null AF: restituisce il numero di volte che "e occorre in a" */ public static int howMany(int[] a, int e)che abbiamo sviluppato la scorsa lezione.
/* AI: a != null AF: restituisce un nuovo array, ottenuto da a eliminando tutte le occorrenze di e */ public static int[] deleteAll(int a[], e) { if (a==null) throw new IllegalArgumentException(); int n = howMany(a,e); int[] b = new int[a.length-n]; int j=0; /* IC: 0 <= i <= a.length AND b[0..j-1] contiene gli elementi di a[0..i-1] diversi da e */ for(i=0; i < a.length; i++) { if (a[i]!=e) { b[j]=a[i]; j++; } } /* b contiene gli elementi di a diversi da e */ return b; }
Questa soluzione usa (oltre al metodo howMany) il metodo:
/* AI: a != null AF: restituisce un nuovo array ottenuto da a eliminando la prima occorrenza di e */ public static int[] deleteFirst(int[] a, int e)che abbiamo sviluppato la scorsa lezione.
/* AI: a != null AF: restituisce un nuovo array, ottenuto da a eliminando tutte le occorrenze di e */ public static int[] deleteAll(int a[], e) { if (a==null) throw new IllegalArgumentException(); int n = howMany(a,e); int[] b = a; /* IC: 0 <= j <= n AND b e' ottenuto da a eliminando le prime j occorrenze di e */ for(j=0; j < n; j++) b = deleteFirst(b,e); /* b contiene gli elementi di a diversi da e */ return b; }Questa soluzione e' "brutta" perche' ogni chiamata di deleteFirst puo' richiedere di visitare un numero consistente di elementi di a (ad es. la meta'), e puo' essere necessario eseguire la deleteFirst per un numero consistente di volte (ad es. la meta' degli elementi di a). Si consideri ad esempio un array di 20000 elementi, costituito da 10000 "zeri" seguiti da 10000 "uni":
Con la prima soluzione, invece, ciascun elemento di a e' visitato una volta, quindi vengono visitati 20000 elementi.
Inoltre la prima soluzione richiede di fare una sola new, per allocare un array che ha alpiu' tanti elementi come a (nell'esempio di prima un array di 10000 elementi). Mentre la seconda soluzione richiede di fare tante new (quante sono le occorrenze di e in a) per allocare array che hanno alpiu' tanti elementi come a (nell'esempio di prima 10000 array di 19999, 19998,...,10000 elementi).
/* AI: AF: L' array a e' stato modificato rimpiazzando tutte le occorrenze di oldE con newE (se a==null non e' stato fatto niente) */ void replaceAll(int a[], oldE, newE) { if (a==null) return; /* IC: 0 <= j <= a.length AND in a[0..i-1] tutte le occorrenze di oldE sono state rimpiazzate da newE */ for (i=0; i < a.length; i++) if (a[i] == oldE) a[i] = newE; /* In a tutte le occorrenze di oldE sono state rimpiazzare da newE */ }
/* AI: a!=nulll AND n>=0 AF: L' array a e' stato modificato rimpiazzando le prime n occorrenze di oldE con newE (se ci sono meno di n occorrenze le rimpiazza tutte) */ void replaceFirst(int a[], oldE, newE, n) { if ((a==null) || (n<0)) throw new IllegalArgumentException(); int counter = 0; int i = 0; /* IC: 0 <= i <= a.length AND 0<= counter <= n AND in a[0..i-1] tutte le occorrenze di oldE (che erano counter) sono state rimpiazzate da newE */ while ((i < a.length) && (counter < n)) { if (a[i]==oldE) a[i] = newE; i++; } }
Per eventuali chiarimenti rivolgersi ai docenti.