Vedere il l'testo del laboratorio 02.
Vedere il'ultima parte della lezione 4 per l'algoritmo del Crivello di Eratostene in Java.
Diamo qui la soluzione all'esercizio che chiedeva:
Scrivere un programma che controlla se un numero
assegnato e' primo oppure no.
|
Il numero da controllare va preso da command-line, quindi una prima modifica da apportare al main e' la seguente (in grassetto la parte modificata):
public static void main(String args) { if (args.length<1) System.out.println("Errore: manca il parametro"); else { int k = Integer.parseInt(args[0]); /* quella che segue e' la parte solita dove abbiamo fatto arrivare il ciclo fino a k compreso */ Sieve first = new Sieve(); int n; for (n=2; n<=k; n++) first.filter(n); } }
Ma dobbiamo ancora modificarlo per riuscire a capire se durante il ciclo abbiamo trovato che k e' primo oppure no.
Ci sono almeno 3 varianti possibili, che vanno tutte bene.
Faccio conoscere a tutti i crivelli quale e' il numero da controllare. Quando un crivello sta setacciando un numero i (nella funzione filter) ed e arrivato a concludere che i e' primo oppure non e' primo, controlla se questo numero i e' uguale al numero da controllare. Se lo e' allora stampa, a seconda del caso, "il numero cercato e' primo" oppure "il numero cercato non e' primo". Negli altri casi non stampa nulla per non appesantire l'output.
In pratica:
static int numberToTest;
Sieve.numberToTest = k;
void filter(int i) { if (myPrime==0) { myPrime = i; if (i==numberToTest) System.out.println("Numero " + i + " e' primo"); } else { if ((i % myPrime)==0) {if (i==numberToTest) System.out.println("Numero " + i + " non e' primo");} else { if (next==null) next = new Sieve(); next.filter(i); } } }
Metto una variabile booleana condivisa da tutti i crivelli. In un generico momento del ciclo del main, quando eseguo first.filter(n), attaccata in coda al primo crivello first si trova una catena di crivelli, e il numero n viene fatto passare per questa catena di crivelli. Uno ed un solo crivello della catena trova che n e' primo oppure che n non e' primo. Se trova che n e' primo, gli facciamo mettere il booleano a true, se trova che non e' primo lo facciamo mettere a false. Quindi dopo ogni giro del ciclo sappiamo se n era primo o no, guardando il valore del booleano. A noi interessa guardarlo all'ultimo giro del ciclo, quello in cui n vale k.
In pratica:
static int numberIsPrime;
void filter(int i) { if (myPrime==0) { myPrime = i; numberIsPrime = true; } else { if ((i % myPrime)==0) numberIsPrime = false; else { if (next==null) next = new Sieve(); next.filter(i); } } }
if (Sieve.numberIsPrime) System.out.println("Numero " + k + "primo"); else System.out.println("Numero " + k + "non primo");
Noto che alla fine del ciclo nel main, ho una catena di crivelli
dei quali il primo contiene 2, il secondo 3, e i seguenti
contengono tutti gli altri numeri primi, l'ultimo crivello
della catena contiene il numero primo
piu' grande che sia minore o uguale a k.
Se k era primo, questo ultimo crivello contiene proprio k.
Percio' per sapere se k e' primo basta andare a prendere
l'ultimo crivello e guardare che numero ha dentro.
In pratica:
Sieve last = first; // parte dal primo while (last.next!=null) last = last.next; // avanza finche' puo' // ora last e' l'ultimo crivello if (last.myPrime==k) System.out.printn("Numero " + k + " primo"); else System.out.printn("Numero " + k + " non primo");
Partire dall'implementazione della classe "rettangolo" da voi scritta,
quella con incapsulazione (le dimensioni del rettangolo
come variabili private e i metodi pubblici
"get" e "set" per leggerle e assegnarle).
Modificare la classe facendo si' che i metodi "set" sollevino
eccezione in caso di argomento negativo, e lo stesso faccia
il costruttore del rettangolo
Scrivere un "main" che legge le dimensioni del rettangolo da
command-line, cerca di costruire il rettangolo.
In caso di eccezione, ricovera l'errore
sostituendo la dimensione negativa con il valore 1.
Poi calcola l'area del rettangolo.
|
Il risultato si ottiene prendendo la classe RectangleExcp dalle dispense e cambiando tre cose:
Vediamo ora il nuovo main:
public static void main(String[] args) { /* legge da command line due numeri interi per le dimensioni del rettangolo */ int input_l = 0; int input_w = 0; if (args.length!=2) { System.out.println("Necessari due interi come argomenti."); System.out.println("Per default: " + input_l + " " + input_w); } else { input_l = Integer.parseInt(args[0]); input_w = Integer.parseInt(args[1]); System.out.println("Argomenti: " + input_l + " " + input_w); } /* costruisce rettangolo finora di dimensioni zero */ RectangleExcp r = new RectangleExcp(); /* prova ad assegnare la lunghezza, se errore mette 1 */ try { r.setLength(input_l); } catch (NegativeRectangleException excp) { System.out.println("Errore, lunghezza negativa " + input_l); try { r.setLength(1); } catch (NegativeRectangleException ee) {} } /* prova ad assegnare la lunghezza, se errore mette 1 */ try { r.setWidth(input_w); } catch (NegativeRectangleException excp) { System.out.println("Errore, larghezza negativa " + input_l); try { r.setWidth(1); } catch (NegativeRectangleException ee) {} } /* ora stampa rettangolo, calcola area e la stampa */ r.print(); int a = r.area(); System.out.println("Area = " + a); }