Il problema
Una variabile, si sa, può contenere un valore alla volta. Supponiamo allora che vogliamo mantenere, contemporaneamente, tutti i tempi che abbiamo
realizzato in un pomeriggio di allenamento in piscina. Per le conoscenze informatiche che abbiamo, il compito sembra piuttosto facile: dichiaro un
certo numero di variabili int
ciascuna delle quali rappresenta un tempo. Potremmo per esempio scrivere:
int t0, t1, t2, t3, t4, t5, t6, t7, t8, t9;
e se di questi tempi vogliamo sapere quanti sono superiori ad un tempo minimo indicato
dal coach, come si fa? L'unica soluzione è controllare variabile per variabile il fatto. L'operazione non può essere inserita in un for
perché non sono righe identiche: cambia (solo e soltanto) il nome della variabile, in particolare cambierebbe solo il numero che abbiamo apposto alla
variabile. Inoltre se un giorno facciamo 15 vasche anziché 10 dobbiamo modificare il programma.
Si può inventare qualcosa per cui le azioni si possono mettere nel ciclo?
La soluzione
Il vettore non è altro che una variabile in grado di contenere contemporaneamente più valori. Quanti? Gli viene detto al momento della
sua creazione. Andando in ordine: prima di tutto il vettore dobbiamo dichiararlo,
come tutte le dichiarazioni questa è composta da un tipo e un nome...
con una piccola aggiunta: []
.
Per dichiarare un vettore di interi chiamato tempi
possiamo scrivere
int [] tempi;
oppure int tempi[];
le due dichiarazioni
sono del tutto equivalenti.
Dove mettere questa dichiarazione? Come al solito, dipende dall'uso:
se il vettore deve essere disponibile in più funzioni oppure sarà utile in una sola funzione
ma dovrà tenere memoria dei valori precedentemente inseriti,
allora la metteremo a livello classe, altrimenti all'interno della funzione.
Dopo la sola dichiarazione il vettore non è però ancora utilizzabile dobbiamo
crearlo (cosa che facciamo anche con gli oggetti dell'interfaccia grafica) e in
questo momento decidiamo quanti elementi deve contenere, ad esempio: tempi = new int[10]
,
10 nel nostro caso.
Come nel caso degli altri oggetti dichiarazione e creazione possono essere fatte
contestualmente: int tempi[] = new int[10]
.
Adesso proviamo a sviluppare il nostro programma che voglio usare in questo modo: dopo gli allenamenti io indicherò quante vasche ho cronometrato, successivamente immetterò un valore alla volta e poi potrò chiedere quante vasche ho nuotato con un tempo inferiore ad un certo valore.
Al momento di scrivere il programma non so quanto dovrà essere grande il vettore, in questo caso si rimanderà l'allocazione della memoria (sarebbe a dire la creazione del vettore) a quando si saprà la grandezza, cioè dopo che l'utente l'avrà comunicata scrivendola in una casella e premendo il pulsante corrispondente:
public class Piscina extends Application { TextField tNumero = new TextField(); int tempi[]; int numTempi; @Override public void start(Stage primaryStage) { /* Quanto necessario... */ } public void alloca() { numTempi = Integer.parseInt(tNumero.getText()); tempi = new int[numTempi]; } }
A cosa serve la variabile numTempi
? Ma semplicemente a ricordare quanti elementi ci sono nel vettore.
Non ci rimane che usarlo. Come accedere? Dato che la variabile rappresenta una collezione di int
dobbiamo indicare quale elemento si
vuole. Tale indicazione si mette tra parentesi quadre. Da osservare che la posizione inizia da 0
quindi se vogliamo leggere al primo
elemento e assegnarlo ad una ipotetica variabile tempo
scriveremo tempo = tempi[0];
. Sarebbe la stessa cosa per la scrittura.
Andiamo con ordine: la prima cosa che si fa in genere con un vettore è il suo caricamento. L'utente inserisce un tempo alla volta in una casella di testo.
Inserirà tale tempo, poi premerà il pulsante e il numero che avrà inserito sarà aggiunto a quelli immessi in precedenza. Ogni numero che inserirà andrà
inserito nella posizione seguente a quella in cui è stato immesso il precedente. Tale azione la svolgeremo ogni volta che l'utente premerà il relativo
pulsante. Per questo useremo in più la variabile pos
che indicherà quanti elementi sono stati immessi fino ad ora. Ecco il codice:
public class Piscina extends Application { TextField tNumero = new TextField(); /* per inserire il numero di tempi */ TextField tTempo = new TextField(); /* per inserire ogni singolo tempo */ int tempi[]; int numTempi; int pos; @Override public void start(Stage primaryStage) { /*Quanto necessario... */ } public void alloca() { numTempi = Integer.parseInt(tNumero.getText()); tempi = new int[numTempi]; pos = 0; } public void inserisciTempo() { if(pos < numTempi) { tempi[pos++]=Integer.parseInt(tTempo.getText()); tTempo.setText(""); /* Così si pulisce la casella di testo rendendola pronta per il prossimo tempo */ } } }
Quale dei seguenti blocchi di codice è equivalente a tempi[pos++]=Integer.parseInt(tTempo.getText());
tempi[pos]=Integer.parseInt(tTempo.getText()); tempi[pos]=Integer.parseInt(tTempo.getText());
pos=pos+1; int o;
o=Integer.parseInt(tTempo.getText());
tempi[pos++]=o
Fatto il caricamento, dobbiamo indicare in una casella di testo quanti sono i tempi superiori a quello previsto dal coach.
Risolviamo il problema col
seguente algoritmo: confronto ciascun tempo a partire dal primo fino all'ultimo con quello del coach. Ogni volta che il tempo risulta superiore incrementerò
di 1 un contatore. Alla fine mostrerò il risultato in una specifica casella di testo. Il codice:
public class Piscina extends Application { TextField tNumero = new TextField(); TextField tTempo = new TextField(); TextField tCoach = new TextField(); TextField tRisultati = new TextField(); int tempi[]; int numTempi; int pos; @Override public void start(Stage primaryStage) { /* Quanto necessario... */ } public void alloca() { numTempi = Integer.parseInt(tNumero.getText()); tempi = new int[numTempi]; pos = 0; } public void inserisciTempo() { if(pos < numTempi) { tempi[pos++]=Integer.parseInt(tTempo.getText()); tTempo.setText(""); } } public void contaPessimi() { int indice, contatore; int coach = Integer.parseInt(tCoach.getText()); for(contatore = indice = 0; indice < numTempi; indice++) { if(tempi[indice] > coach) { contatore++; } } tRisultati.setText("" + contatore); } }
In realtà non serve una variabile aggiuntiva per conoscere di quanti elementi dispone il vettore. Questo è fattibile tramite la proprietà length
del vettore stesso: questa proprietà fornisce infatti il numero di elementi; ad esempio tempi.length
conterrà quanto indicato
dall'utente. Possiamo allora modificare l'esempio appena qui sopra:
public class Piscina extends Application { TextField tNumero = new TextField(); TextField tTempo = new TextField(); TextField tCoach = new TextField(); TextField tRisultati = new TextField(); int tempi[]; int pos; @Override public void start(Stage primaryStage) { /* Quanto necessario... */ } public void alloca() { tempi = new int[Integer.parseInt(tNumero.getText())]; pos = 0; } public void inserisciTempo() { if(pos < tempi.length) { tempi[pos++]=Integer.parseInt(tTempo.getText()); tTempo.setText(""); } } public void contaPessimi() { int indice, contatore; int coach = Integer.parseInt(tCoach.getText()); for(contatore = indice = 0; indice < tempi.length; indice++) { if(tempi[indice] > coach) { contatore++; } } tRisultati.setText("" + contatore); } }
Per una squadra di calcio viene data una casella di testo tSquadra1
, una casella di testo
tPuntiSquadra1
con relativo pulsante inserisciRisultato1
ed in modo simmetrico per la seconda squadra di
calcio la casella tSquadra2
, tPuntiSquadra2
e inserisciRisultato2
. Si inserisce
nella casella di testo del punteggio il valore 0
se la squadra ha perso; il punteggio 1
se ha pareggiato ed in fine 2
se ha vinto. Tali valori si devono inserire per le ultime 5 partite, quindi ti dovrai appoggiare ad un vettore per la prima squadra ed un altro per la
seconda. Proprio come detto sopra, quando l'utente premerà il pulsante, il vecchio risultato si dovrà cancellare per facilitare l'immissione del nuovo.
Aggiungi ora una casella di testo per fornire il risultato (tRisultato
) ed il relativo pulsante per calcolarlo
(calcolaRisultato
): scrivere il nome della squadra che ha maggiore probabilità di vincere uno scontro diretto (confronta le somme).