Esercizi · Introduzione a Java¶
Esercizi · Capitolo 8 · ogni soluzione si apre con un clic · Capitolo 8: Introduzione a Java · Eserciziario, volume 2 (PDF)
Negli esercizi di questo capitolo i programmi sono scritti, compilati ed eseguiti con le convenzioni del capitolo «Introduzione a Java», riassunte qui sotto.
Codice
-
Il programma di un esercizio è una classe
Main, salvata nel fileMain.java(ogni esercizio in una cartella propria), compilata ed eseguita con i comandi -
I metodi sono metodi
staticdella classeMain. Le istanze di test sono array scritti nel codice, ad esempioint[] arr1 = {9, 12, 3, 16, 19, 11, 12};, e sono passate ai metodi senza la loro dimensione: un metodo ottiene la dimensione \(n\) di un arrayacona.length. -
Gli elementi di un array di dimensione \(n\) sono
a[0],a[1], …,a[n-1]: la componente \(a[i]\) di un'istanza scritta come \(a = [\dots]\) nel testo corrisponde ada[i-1]nel codice, e gli indici stampati dai programmi partono da \(0\). -
Un metodo restituisce al più un valore: i risultati che un metodo deve restituire insieme sono restituiti in un array (
int[]odouble[]). -
Quando un array è stampato con un ciclo, ogni valore è seguito da uno spazio, quindi le righe stampate terminano con uno spazio.
-
Il formato
%.4fdiprintfvisualizza un numero in virgola mobile con esattamente \(4\) cifre dopo la virgola decimale. Gli output sono quelli di un calcolatore con impostazioni in inglese: con le impostazioni in italianoprintfscrive la virgola decimale (11,7143).
Esercizio 8.1: Introduzione a {\tt Java} (E1)
Dato un array \(a\) di \(n \ge 1\) numeri interi, consideriamo il problema di trovare il valore massimo nell'array.
Domande
-
Scrivere un programma
Javacompleto che trova il valore massimo in un array \(a\) di \(n\) numeri interi. Il programma deve:-
definire un metodo statico
int arrayMaxValue(int[] a)dentro la classeMain; -
nel metodo
main, creare gli array di test e chiamare il metodo; -
stampare i risultati per ogni caso di test.
-
-
Eseguire il programma sulle seguenti istanze:
-
Istanza 1: \(a = [9, 12, 3, 16, 19, 11, 12]\) con \(n=7\)
-
Istanza 2: \(a = [5, 2, 8, 1]\) con \(n=4\)
-
Istanza 3: \(a = [42]\) con \(n=1\)
Mostrare i comandi di compilazione ed esecuzione e l'output per tutti i casi di test.
-
-
Modificare il metodo in modo che restituisca sia il valore massimo sia il suo indice. Poiché un metodo
Javarestituisce un solo valore, restituire un arrayint[]di due elementi:{maxValue, maxIndex}. Eseguire la versione modificata sull'Istanza 1 e mostrare l'output.
Soluzione
-
Programma
Javacompleto:public class Main { static int arrayMaxValue(int[] a) { int max = a[0]; // Inizializza con il primo elemento for (int i = 1; i < a.length; i++) { if (a[i] > max) { max = a[i]; // Aggiorna il massimo } } return max; } public static void main(String[] args) { int[] arr1 = {9, 12, 3, 16, 19, 11, 12}; System.out.print("Prova 1 - Array: "); for (int x : arr1) System.out.print(x + " "); System.out.println(); System.out.println("Valore massimo: " + arrayMaxValue(arr1)); System.out.println(); int[] arr2 = {5, 2, 8, 1}; System.out.print("Prova 2 - Array: "); for (int x : arr2) System.out.print(x + " "); System.out.println(); System.out.println("Valore massimo: " + arrayMaxValue(arr2)); System.out.println(); int[] arr3 = {42}; System.out.print("Prova 3 - Array: "); for (int x : arr3) System.out.print(x + " "); System.out.println(); System.out.println("Valore massimo: " + arrayMaxValue(arr3)); } }Gli array sono stampati con il ciclo
foresteso, che visita direttamente i loro elementi. Per l'Istanza 3 la condizione1 < a.lengthè falsa fin dall'inizio, il ciclo non esegue nessuna iterazione, e il metodo restituisce l'unico elementoa[0]. -
Compilazione ed esecuzione:
Output:
-
Metodo modificato che restituisce il valore massimo e il suo indice:
public class Main { // Restituisce int[]{maxValue, maxIndex} static int[] arrayMaxValueWithIndex(int[] a) { int max = a[0]; int idx = 0; for (int i = 1; i < a.length; i++) { if (a[i] > max) { max = a[i]; idx = i; // Memorizza l'indice } } return new int[]{max, idx}; } public static void main(String[] args) { int[] arr1 = {9, 12, 3, 16, 19, 11, 12}; int[] result = arrayMaxValueWithIndex(arr1); System.out.println("Valore massimo: " + result[0] + ", all'indice: " + result[1]); } }Output:
Per l'Istanza 1 il metodo restituisce l'array \(\{19,\ 4\}\): il valore massimo \(19\) è all'indice \(4\) (indici da \(0\)), cioè nella posizione \(5\) dell'array \(a[1..7]\) del testo. Se il valore massimo compare più volte, il metodo restituisce l'indice della sua prima occorrenza, perché
maxeidxsono aggiornati solo quandoa[i] > max(disuguaglianza stretta).
Esercizio 8.2: Introduzione a {\tt Java} (E2)
Dato un array \(a\) di \(n \ge 1\) numeri interi, consideriamo il problema di trovare il valore minimo nell'array.
Domande
-
Scrivere un programma
Javacompleto che trova il valore minimo in un array \(a\) di \(n\) numeri interi. Il programma deve:-
definire un metodo statico
int arrayMinValue(int[] a)dentro la classeMain; -
nel metodo
main, creare gli array di test e chiamare il metodo; -
stampare i risultati per ogni caso di test.
-
-
Eseguire il programma sulle seguenti istanze:
-
Istanza 1: \(a = [9, 12, 3, 16, 19, 11, 12]\) con \(n=7\)
-
Istanza 2: \(a = [5, 2, 8, 1]\) con \(n=4\)
-
Istanza 3: \(a = [42]\) con \(n=1\)
Mostrare i comandi di compilazione ed esecuzione e l'output per tutti i casi di test.
-
-
Modificare il metodo in modo che restituisca sia il valore minimo sia il suo indice. Poiché un metodo
Javarestituisce un solo valore, restituire un arrayint[]di due elementi:{minValue, minIndex}. Eseguire la versione modificata sull'Istanza 1 e mostrare l'output.
Soluzione
-
Programma
Javacompleto:public class Main { static int arrayMinValue(int[] a) { int min = a[0]; // Inizializza con il primo elemento for (int i = 1; i < a.length; i++) { if (a[i] < min) { min = a[i]; // Aggiorna il minimo } } return min; } public static void main(String[] args) { int[] arr1 = {9, 12, 3, 16, 19, 11, 12}; System.out.print("Prova 1 - Array: "); for (int x : arr1) System.out.print(x + " "); System.out.println(); System.out.println("Valore minimo: " + arrayMinValue(arr1)); System.out.println(); int[] arr2 = {5, 2, 8, 1}; System.out.print("Prova 2 - Array: "); for (int x : arr2) System.out.print(x + " "); System.out.println(); System.out.println("Valore minimo: " + arrayMinValue(arr2)); System.out.println(); int[] arr3 = {42}; System.out.print("Prova 3 - Array: "); for (int x : arr3) System.out.print(x + " "); System.out.println(); System.out.println("Valore minimo: " + arrayMinValue(arr3)); } }Gli array sono stampati con il ciclo
foresteso, che visita direttamente i loro elementi. Per l'Istanza 3 la condizione1 < a.lengthè falsa fin dall'inizio, il ciclo non esegue nessuna iterazione, e il metodo restituisce l'unico elementoa[0]. -
Compilazione ed esecuzione:
Output:
-
Metodo modificato che restituisce il valore minimo e il suo indice:
public class Main { // Restituisce int[]{minValue, minIndex} static int[] arrayMinValueWithIndex(int[] a) { int min = a[0]; int idx = 0; for (int i = 1; i < a.length; i++) { if (a[i] < min) { min = a[i]; idx = i; // Memorizza l'indice } } return new int[]{min, idx}; } public static void main(String[] args) { int[] arr1 = {9, 12, 3, 16, 19, 11, 12}; int[] result = arrayMinValueWithIndex(arr1); System.out.println("Valore minimo: " + result[0] + ", all'indice: " + result[1]); } }Output:
Per l'Istanza 1 il metodo restituisce l'array \(\{3,\ 2\}\): il valore minimo \(3\) è all'indice \(2\) (indici da \(0\)), cioè nella posizione \(3\) dell'array \(a[1..7]\) del testo. Se il valore minimo compare più volte, il metodo restituisce l'indice della sua prima occorrenza, perché
mineidxsono aggiornati solo quandoa[i] < min(disuguaglianza stretta).
Esercizio 8.3: Introduzione a {\tt Java} (E3)
Dato un array \(a\) di \(n \ge 1\) numeri interi, consideriamo il problema di calcolare la somma e la media di tutti i suoi elementi.
Domande
-
Scrivere un programma
Javacompleto che calcola la somma e la media degli elementi di un array \(a\) di \(n\) numeri interi. Il programma deve:-
definire un metodo statico
int arraySum(int[] a)che restituisce la somma; -
definire un metodo statico
double arrayAverage(int[] a)che restituisce la media; -
nel metodo
main, creare gli array di test, chiamare entrambi i metodi e stampare i risultati, con la media arrotondata a \(4\) cifre decimali.
-
-
Eseguire il programma sulle seguenti istanze:
-
Istanza 1: \(a = [9, 12, 3, 16, 19, 11, 12]\) con \(n=7\)
-
Istanza 2: \(a = [5, 2, 8, 1]\) con \(n=4\)
-
Istanza 3: \(a = [42]\) con \(n=1\)
Mostrare i comandi di compilazione ed esecuzione e l'output per tutti i casi di test.
-
-
Scrivere un unico metodo
arraySumAndAverage(int[] a)che restituisce sia la somma sia la media. Poiché un metodoJavarestituisce un solo valore, restituire il risultato come un arraydouble[]di due elementi:{sum, average}. Eseguirlo sull'Istanza 1 e mostrare l'output.
Soluzione
-
Programma
Javacompleto:public class Main { static int arraySum(int[] a) { int total = 0; for (int i = 0; i < a.length; i++) { total += a[i]; } return total; } static double arrayAverage(int[] a) { return (double) arraySum(a) / a.length; } static void printTest(int k, int[] a) { System.out.print("Prova " + k + " - Array: "); for (int x : a) System.out.print(x + " "); System.out.println(); System.out.println("Somma: " + arraySum(a)); System.out.printf("Media: %.4f%n", arrayAverage(a)); } public static void main(String[] args) { int[] arr1 = {9, 12, 3, 16, 19, 11, 12}; printTest(1, arr1); System.out.println(); int[] arr2 = {5, 2, 8, 1}; printTest(2, arr2); System.out.println(); int[] arr3 = {42}; printTest(3, arr3); } }La conversione
(double)è necessaria: senza di essa,arraySum(a) / a.lengthsarebbe la divisione intera, e per l'Istanza 1 la media sarebbe \(82/7 = 11\). Il metodoprintTeststampa l'array e i due risultati, ed evita di scrivere tre volte le stesse istruzioni. -
Compilazione ed esecuzione:
Output:
Prova 1 - Array: 9 12 3 16 19 11 12 Somma: 82 Media: 11.7143 Prova 2 - Array: 5 2 8 1 Somma: 16 Media: 4.0000 Prova 3 - Array: 42 Somma: 42 Media: 42.0000Per l'Istanza 1 la media esatta è \(82/7 = 11.714285\ldots\), visualizzata come \(11.7143\).
-
Metodo combinato:
public class Main { // Restituisce double[]{somma, media} static double[] arraySumAndAverage(int[] a) { int total = 0; for (int x : a) total += x; double avg = (double) total / a.length; return new double[]{total, avg}; } public static void main(String[] args) { int[] arr1 = {9, 12, 3, 16, 19, 11, 12}; double[] result = arraySumAndAverage(arr1); System.out.printf("Somma: %.0f, Media: %.4f%n", result[0], result[1]); } }Output:
L'intero
totalè convertito automaticamente in undoublequando viene memorizzato nell'arraydouble[]; per questo motivo è stampato con il formato%.0f(nessuna cifra decimale) invece di%d, che accetta solo interi.
Esercizio 8.4: Introduzione a {\tt Java} (E4)
Dato un array \(a\) di \(n\) numeri interi e un valore \(m\), consideriamo il problema di determinare se il valore \(m\) è presente o no nell'array.
Domande
-
Scrivere un programma
Javacompleto che esegue una ricerca lineare in un array \(a\). Il programma deve:-
definire un metodo statico
int linearSearch(int[] a, int m)che cerca il valoremnell'arraya; -
restituire l'indice della prima occorrenza di
mse viene trovato, oppure-1se non viene trovato; -
nel metodo
main, eseguire i casi di test e stampare i risultati.
-
-
Eseguire il programma sull'array \(a = [9, 12, 3, 16, 19, 11, 12]\) con i seguenti valori:
-
\(m = 16\) (presente nell'array)
-
\(m = 12\) (presente due volte: si restituisce l'indice della prima occorrenza)
-
\(m = 7\) (non presente nell'array)
Mostrare i comandi di compilazione ed esecuzione e l'output per tutti i casi di test.
-
-
Modificare il metodo in modo che restituisca un array
int[]contenente tutti gli indici in cui compare il valore \(m\) (invece della sola prima occorrenza). Usare unaArrayList<Integer>dentro il metodo e convertirla in unint[]prima di restituirla. Eseguirlo con \(m = 12\) e mostrare l'output.
Soluzione
-
Programma
Javacompleto:public class Main { static int linearSearch(int[] a, int m) { for (int i = 0; i < a.length; i++) { if (a[i] == m) { return i; // Trovato: restituisce l'indice } } return -1; // Non trovato } static void printResult(int[] a, int m) { int idx = linearSearch(a, m); if (idx != -1) System.out.println("Valore " + m + " trovato all'indice " + idx); else System.out.println("Valore " + m + " non trovato"); } public static void main(String[] args) { int[] a = {9, 12, 3, 16, 19, 11, 12}; System.out.print("Array: "); for (int x : a) System.out.print(x + " "); System.out.println(); System.out.println(); printResult(a, 16); printResult(a, 12); printResult(a, 7); } }L'istruzione
return itermina il metodo, e quindi il ciclo, alla prima occorrenza dim; l'istruzionereturn -1viene raggiunta solo quando il ciclo ha visitato l'intero array senza trovarem. Si usa il valore-1perché non può essere un indice dell'array. -
Compilazione ed esecuzione:
Output:
Array: 9 12 3 16 19 11 12 Valore 16 trovato all'indice 3 Valore 12 trovato all'indice 1 Valore 7 non trovatoIl valore \(12\) si trova negli indici \(1\) e \(6\), e il metodo restituisce il primo. Nell'array \(a[1..7]\) del testo, gli indici \(3\) e \(1\) corrispondono alle posizioni \(4\) e \(2\).
-
Metodo che restituisce tutte le occorrenze:
import java.util.ArrayList; public class Main { static int[] linearSearchAll(int[] a, int m) { ArrayList<Integer> indices = new ArrayList<>(); for (int i = 0; i < a.length; i++) { if (a[i] == m) { indices.add(i); } } // Conversione della ArrayList<Integer> in un int[] int[] result = new int[indices.size()]; for (int i = 0; i < indices.size(); i++) { result[i] = indices.get(i); } return result; } public static void main(String[] args) { int[] a = {9, 12, 3, 16, 19, 11, 12}; int m = 12; int[] occurrences = linearSearchAll(a, m); if (occurrences.length > 0) { System.out.print("Valore " + m + " trovato agli indici: "); for (int idx : occurrences) System.out.print(idx + " "); System.out.println(); } else { System.out.println("Valore " + m + " non trovato"); } } }Output:
Il numero di occorrenze non è noto in anticipo, quindi gli indici sono prima raccolti in una
ArrayList, che cresce conadd; poi si alloca e si riempie un array della dimensione giustaindices.size(). A differenza dilinearSearch, questo metodo visita sempre l'intero array. Semnon è presente, il metodo restituisce un array di lunghezza \(0\).
Esercizio 8.5: Introduzione a {\tt Java} (E5)
Dato un array \(a\) di \(n \ge 1\) numeri interi, consideriamo il problema di calcolare in un solo passaggio il massimo, il minimo, la somma e la media di tutti gli elementi dell'array.
Domande
-
Scrivere un programma
Javacompleto che calcola in un solo passaggio le quattro statistiche (massimo, minimo, somma, media) di un array \(a\) di \(n\) numeri interi. Il programma deve:-
definire un metodo statico
arrayStats(int[] a)che calcola i quattro valori con un solo ciclo; -
restituire i risultati come un array
double[]di quattro elementi:{max, min, sum, average}; -
nel metodo
main, eseguire i casi di test e stampare i risultati.
-
-
Eseguire il programma sulle seguenti istanze:
-
Istanza 1: \(a = [9, 12, 3, 16, 19, 11, 12]\) con \(n=7\)
-
Istanza 2: \(a = [5, 2, 8, 1]\) con \(n=4\)
-
Istanza 3: \(a = [42]\) con \(n=1\)
Mostrare i comandi di compilazione ed esecuzione e l'output per tutti i casi di test.
-
-
Modificare il metodo in modo che restituisca anche gli indici dell'elemento massimo e dell'elemento minimo, come un array
double[]di sei elementi:{max, maxIdx, min, minIdx, sum, average}. Eseguirlo sull'Istanza 1 e mostrare l'output.
Soluzione
-
Programma
Javacompleto:public class Main { // Restituisce double[]{massimo, minimo, somma, media} static double[] arrayStats(int[] a) { int max = a[0]; int min = a[0]; int total = a[0]; for (int i = 1; i < a.length; i++) { if (a[i] > max) max = a[i]; if (a[i] < min) min = a[i]; total += a[i]; } double avg = (double) total / a.length; return new double[]{max, min, total, avg}; } static void printStats(int k, int[] a) { double[] s = arrayStats(a); System.out.print("Prova " + k + " - Array: "); for (int x : a) System.out.print(x + " "); System.out.println(); System.out.println(" Massimo: " + (int) s[0]); System.out.println(" Minimo: " + (int) s[1]); System.out.println(" Somma: " + (int) s[2]); System.out.printf(" Media: %.4f%n", s[3]); } public static void main(String[] args) { printStats(1, new int[]{9, 12, 3, 16, 19, 11, 12}); System.out.println(); printStats(2, new int[]{5, 2, 8, 1}); System.out.println(); printStats(3, new int[]{42}); } }Le tre variabili sono inizializzate con il primo elemento, e il ciclo visita una sola volta gli altri \(n-1\) elementi. I quattro risultati hanno tipi di dato diversi, quindi sono tutti memorizzati come
doublenell'array restituito; i risultati interi sono riconvertiti con(int)prima della stampa, in modo che siano visualizzati senza la parte decimale (19invece di19.0). L'espressionenew int[]{…}crea un array direttamente nella chiamata. -
Compilazione ed esecuzione:
Output:
-
Metodo esteso che restituisce anche gli indici:
public class Main { // Restituisce double[]{max, maxIdx, min, minIdx, somma, media} static double[] arrayStatsWithIndices(int[] a) { int max = a[0], maxIdx = 0; int min = a[0], minIdx = 0; int total = a[0]; for (int i = 1; i < a.length; i++) { if (a[i] > max) { max = a[i]; maxIdx = i; } if (a[i] < min) { min = a[i]; minIdx = i; } total += a[i]; } double avg = (double) total / a.length; return new double[]{max, maxIdx, min, minIdx, total, avg}; } public static void main(String[] args) { int[] a = {9, 12, 3, 16, 19, 11, 12}; double[] r = arrayStatsWithIndices(a); System.out.println("Max: " + (int) r[0] + " all'indice " + (int) r[1]); System.out.println("Min: " + (int) r[2] + " all'indice " + (int) r[3]); System.out.println("Somma: " + (int) r[4]); System.out.printf("Media: %.4f%n", r[5]); } }Output:
Il massimo \(19\) è all'indice \(4\) e il minimo \(3\) all'indice \(2\) (indici da \(0\)), cioè nelle posizioni \(5\) e \(3\) dell'array \(a[1..7]\) del testo.