ARRAY E STRINGHE G. Frosini Slide 1
Array: VARIABILI ARRAY struttura dati costituita da elementi (anche nessuno, array vuoto) dello stesso tipo; tipo array: tipo degli elementi, non numero degli elementi; in Java gli array sono oggetti, riferiti da variabili array (riferimenti nella terminologia Java). Variabile array: definizione di una variabile array (riferimento): tipoelementi [] identificatore; Esempio: int[] ar; // definizione della variabile ar di tipo int[] ar la variabile ar è un riferimento destinato a contenere indirizzi di oggetti di tipo array di interi. G. Frosini Slide 2
OGGETTI ARRAY Oggetto array viene creato in memoria dinamica con l operatore new, che (oltre all effetto collaterale della creazione) restituisce come risultato l indirizzo dell oggetto creato; tale indirizzo viene (comunemente) memorizzato in una variabile array; la lunghezza dell array (numero di elementi) viene memorizzata, all atto della creazione dell oggetto, in una variabile length (variabile final) che fa parte dell oggetto stesso. variabilearray = new tipoelementi [numeroelementi] Esempio: ar = new int[3]; viene creato l oggetto array di 3 interi, il cui indirizzo viene memorizzato in ar; ar.length: ha per valore la costante 3. Applicazione dell operatore. : dereferenziazione di ar; selezione del membro length. indirizzo dell oggetto La definizione di una variabile array e la creazione di un oggetto array possono essere anche contestuali: esempio: int[] ar = new int[3]; ar variabile array ar.length oggetto array array G. Frosini Slide 3
ELEMENTI DI UN ARRAY Elementi: se presenti, sono numerati da 0 a length-1; vengono selezionati, attraverso un indice di posizione, applicando a una variabile array l operatore [] ; questo operatore effettua il test di validità dell indice in fase di esecuzione. l applicazione dell operatore [] comporta: la dereferenziazione di ar, ottenendo l indirizzo dell oggetto; la selezione di un elemento all interno dell array contenuto nell oggetto. Esempi: ar[2] = 10; int n = ar[1]; indirizzo dell oggetto ar[3] = 5; // segnalazione di errore in fase di esecuzione Inizializzazione di un oggetto array con un aggregato: ar int[] aa = { 5, 3, 7, 9 ; viene definita una variabile array aa; viene creato in memoria dinamica un oggetto array di 4 elementi, ciascuno con valore iniziale, e l indirizzo dell oggetto creato viene memorizzato nel riferimento aa. ar[1] G. Frosini Slide 4
ESEMPIO: INTERO POSITIVO IN 32 CIFRE BINARIE Trasformazione di un intero maggiore o uguale a 0 (positivo) in un array di 32 caratteri, '0' oppure '1', corrispondenti alle cifre binarie. public class CalcolaArrayBinarioP { public static void main(string[] args) { char c; int i, cifra, numero; char[] ac = new char[32]; Console.scriviStringa("Scrivi un numero intero maggiore o uguale a 0:"); numero = Console.leggiIntero(); for (i=0; i < 32; i++) { cifra = numero % 2; numero = numero / 2; c = (char)(cifra + '0'); ac[31-i] = c; for(i = 0; i < 32; i++) Console.scriviUnCarattere(ac[i]); Console.nuovaLinea(); Il programma può essere utilizzato per esaminare la codifica di un intero qualunque o (cambiando il numero di ieterazioni del for da 32 a 16) quella di un carattere (unicode). G. Frosini Slide 5
ARGOMENTI DI TIPO ARRAY Funzioni: possono avere come argomento formale un riferimento di un tipo array; possono avere come argomento attuale un riferimento dello stesso tipo, riferimento di un oggetto array di dimensioni qualsivoglia. Esempio: programma che calcola la somma degli elementi di un oggetto array di interi di qualunque dimensione, riferito da una variabile riferimento v : public class SommaA { static int somma(int[] v) { int i, s = 0; for (i = 0; i < v.length; i++) s += v[i]; return s; static public void main(string[] args) { int[] a = { 1, 2, 3 ; int[] b = { 11, 12, 13, 14, 15 ; Console.scriviIntero (somma(a)); Console.scriviIntero(somma(b)); G. Frosini Slide 6
ARGOMENTI RIFERIMENTI Argomenti di una funzione: sempre valori; se riferimenti, valori dei riferimenti; Modifiche agli argomenti formali: non hanno alcuna ripercussione sugli argomenti attuali. Argomenti formali riferimento: consentono di modificare l oggetto riferito (se trattasi di un array, i suoi elementi); il riferimento attuale consente di modificare l oggetto attualmente riferito. G. Frosini Slide 7
RADDOPPIO DI UN INTERO E DI UN ARRAY public class RaddoppiaIntero { static void raddoppiai(int n) { n *= 2; public static void main(string[] args) { int i; int num = 10; raddoppiai(num); Console.scriviIntero(num); // non raddoppia: scrive 10 num 10 Raddoppia il contenuto dell argomento raddoppiai n public class RaddoppiaArray { static void raddoppiaa(int[] a) { int i; for (i=0; i<a.length; i++) a[i] *= 2; raddoppiaa public static void main(string[] args) { int i; int[] vett = new int[3]; for (i =0; i<3; i++) vett[i] = i; raddoppiaa(vett); for (i =0; i<3; i++) Console.scriviInt(vett[i]); Console.nuovaLinea(); // raddoppia: scrive 0 2 4 Raddoppia il contenuto dell array riferito dal argomento a vett A[0]... G. Frosini Slide 8
OPERAZIONI SUGLI ARRAY (1) Assegnamento: int[] ar1 = ; int[] ar2 = ; ar1 = ar2; avviene fra variabili array, e quindi fra riferimenti (che riferiscono oggetti array con lo stesso tipo di elementi, non necessariamente con lo stesso numero): Uguaglianza: dopo l assegnamento precedente, le due variabili array ar1 e ar2 contengono l indirizzo dello stesso oggetto array. ar1 == ar2; // uguale ar1!=ar2; // diverso avviene fra variabili array, e quindi fra riferimenti. l operatore uguale (diverso) restituisce true o false a seconda che le variabili riferiscano o non riferiscano (non riferiscano o riferiscano) lo stesso oggetto array. G. Frosini Slide 9
OPERAZIONI SUGLI ARRAY (2) Ricopiamento di array: System.arraycopy(Object ar1, int i1, Object ar2, int i2, int quanti ) ricopia dall array ar1 (a partire dall indice i1) nell array ar2 (a partire dall indice i2) quanti elementi. Uguaglianza fra array (occorre includere il package java.util.*): boolean Arrays.equals(Object ar1, Object ar2 ) l uguaglianza si verifica se: gli array sono dello stesso tipo (elementi dello stesso tipo), hanno la stessa lunghezza, e gli elementi in posizione corrispondente sono uguali. G. Frosini Slide 10
ARRAY MULTIDIMENSIONALI Array multidimensionali un array (primario) può avere come elementi altri array (secondari); in questo caso negli elementi dell array primario sono memorizzati i riferimenti degli array secondari (e non direttamente gli array secondari); gli array secondari, pur dovendo essere dello stesso tipo, non è detto che abbiano lo stesso numero di elementi; se hanno lo stesso numero di elementi, si ottengono le matrici. int[] a = { 1,2, b = { 1, 2, 3, c = { 1 ; int[][] aa = new int[3][]; // la variabile array aa ha tre elementi, // ognuno dei quali è un array di interi aa[0] = a; aa[1] = b; aa[2] = c; aa 1 2 1 2 3 a b 1 c G. Frosini Slide 11
MATRICI Array di array di ugual dimensione: elementi interi, nr = numero righe, nc numero colonne; int[][] m = new int[nr][]; for(i=0; i<nr; i++) m[i] = new int[nc]; Si può anche scrivere: int[][] m = new int[nr][nc]; Esempio: public class Matrice { public static void main(string[] args) { int i, j; int[][] m = new int[3][4]; for(i=0; i<m.length; i++) for(j=0; j<m[i].length; j++) m[i][j] = i*4+j; for(i=0; i<m.length; i++) { for(j=0; j<m[i].length; j++) Console.scriviInt(m[i][j]); Console.nuovaLinea(); // uscita: // 0 1 2 3 // 4 5 6 7 // 8 9 10 11 G. Frosini Slide 12
ORDINAMENTO DI UN ARRAY Algoritmo elementare: confrontare ogni elemento con il successivo, scambiando eventualmente gli elementi di posto; ripetere il tutto fino a quando l array viene scorso senza scambi. public class Ordina { static void sort(int[] v) { boolean ordinato; int i, t; do { ordinato = true; for (i = 0; i < v.length-1; i++) if (v[i] > v[i+1]) { ordinato = false; t = v[i+1]; v[i+1] = v[i]; v[i] = t; while (!ordinato); public static void main(string[] args) { int i; int[] vett = new int[8]; Console.scriviStringa("Scrivi 8 interi"); for (i=0; i<vett.length; i++) vett[i] = Console.leggiIntero(); sort(vett); for (i=0; i<vett.length; i++) Console.scriviInt(vett[i]); Console.nuovaLinea(); G. Frosini Slide 13
RICERCA IN UN ARRAY Problema: funzione che cerca se una data entità (chiave) è presente all'interno di una tabella ordinata (ipotesi: non vi sono chiavi uguali); la ricerca, se positiva, fornisce un risultato, che nel caso più semplice è l indice dell elemento trovato; caso considerato: la tabella è un array di interi. Algoritmo (ricerca binaria o logaritmica): confrontare la chiave cercata con l'elemento di mezzo della tabella; se questi sono uguali la ricerca termina, altrimenti: se la chiave è minore dell elemento di mezzo la ricerca prosegue (con le stesse regole) nella prima metà della tabella; se la chiave è maggiore dell elemento di mezzo la ricerca prosegue (con le stesse regole) nella seconda metà della tabella. Quando la ricerca prosegue, può accadere che la metà considerata sia vuota, e in questo caso l'elemento cercato non si trova nella tabella. G. Frosini Slide 14
ESEMPIO DI RICERCA BINARIA Risultato intero: posizione della chiave, oppure -1 (chiave non trovata). public class RicercaB { static int ricbin(int[] tab, int infe, int supe, int k) { if (supe < infe) return -1; // tabella vuota int medio = (infe + supe) / 2; if (k == tab[medio]) return medio; // elem. trovato if (k < tab[medio]) return ricbin(tab, infe, medio-1, k); return ricbin(tab, medio+1, supe, k); public static void main(string[] args) { int i, key, pos; int[] vett = new int[10]; Console.scriviStringa("Scrvi 10 interi:"); for(i=0; i<vett.length; i++) vett[i] = Console.leggiIntero(); Console.scriviStringa("Scrivi una chiave intera:"); key = Console.leggiIntero(); pos = ricbin(vett, 0, vett.length-1, key); if (pos == -1) Console.scriviStringa("Chiave non trovata"); else Console.scriviIntero(pos); G. Frosini Slide 15
PILA CON ARRAY Pila: insieme ordinato di dati di ugual tipo, in cui sono possibili inserimenti ed estrazioni con la seguente regola: ultimo inserito primo estratto (LIFO). Realizzazione utilizzando un array stack e un indice top: top 0 stack.length-1 top è l indice dell ultimo dato inserito. Inserimento: incremento di top, memorizzazione di un dato. Estrazione: prelievo di un dato, decremento di top. Pila vuota: top uguale a -1. Pila piena: top uguale a stack.length-1. G. Frosini Slide 16
ESEMPIO DI PILA CON ARRAY public class Pila { static int[] stack = new int[5]; static int top = -1; static boolean empty() { if (top == -1) return true; return false; static boolean full() { if (top == stack.length-1) return true; return false; static void push(int s) { if (top!=stack.length-1) { top++; stack[top] = s; static int pop() { int s = 0; if (top!=-1) { s = stack[top]; top--; return s; public static void main(string[] args) { int i, n, m; Console.scriviStringa("Quanti numeri vuoi inserire?:"); n = Console.leggiIntero(); Console.scriviStringa("Sequenza di numeri da inserire:"); for (i = 0; i < n; i++) { m = Console.leggiIntero(); if(!full()) { push(m); Console.scriviStr("Inserito numero "); Console.scriviIntero(m); else Console.scriviStringa("Pila piena"); Console.scriviStringa("Quanti numeri vuoi estrarre?"); n = Console.leggiIntero(); for (i = 0; i < n; i++) if(!empty()) { m = pop(); Console.scriviStr("Estratto Numero "); Console.scriviIntero(m); else Console.scriviStringa("Pila vuota"); G. Frosini Slide 17
CODA CON ARRAY Coda: insieme ordinato di dati di ugual tipo, in cui sono possibili inserimenti ed estrazioni con la seguente regola: primo inserito primo estratto (FIFO). Realizzazione utilizzando un array (circolare) queue e due indici: front back 0 queue.length-1 back è l indice della prossima immissione front è l indice della prossima estrazione quanti è il numero di elementi presenti Immissione: memorizzazione di un dato e incremento (circolare) di back. Estrazione: prelievo di un dato e incremento (circolare) di front. Coda vuota: quanti uguale a 0. Coda piena: quanti uguale a queue.length G. Frosini Slide 18
ESEMPIO DI CODA CON ARRAY public class Coda { static int front = 0, back = 0, quanti = 0; static int[] queue = new int[5]; static boolean empty() { if (quanti == 0) return true; return false; static boolean full() { if (quanti == queue.length) return true; return false; static void immetti(int s) { if (quanti!= queue.length) { queue[back] = s; back = (back+1)%queue.length; quanti++; static int estrai() { int s = 0 ; if (quanti!= 0) { s = queue[front]; front = (front+1)%queue.length; quanti--; return s; public static void main(string[] args) { int i, n, m; Console.scriviStringa("Quanti numeri vuoi inserire?"); n = Console.leggiIntero(); Console.scriviStringa("Sequenza di numeri da inserire:"); for (i = 0; i < n; i++) { m = Console.leggiIntero(); if(!full()) { immetti(m); Console.scriviStr("Inserito numero "); Console.scriviIntero(m); else Console.scriviStringa("Coda piena"); Console.scriviStringa("Quanti numeri vuoi estrarre?"); n = Console.leggiIntero(); for (i = 0; i < n; i++) if(!empty()) { m = estrai(); Console.scriviStr("Estratto Numero "); Console.scriviIntero(m); else Console.scriviStringa("Coda vuota"); G. Frosini Slide 19
STRINGHE (1) Stringa: sequenza di caratteri, anche nessun carattere (stringa vuota). Classe String: tipo, per stringhe costanti. Variabili String (informalmente, di tipo stringa) e oggetti String: una variabile stringa è un riferimento a un oggetto stringa, allocato in memoria dinamica: oggetto stringa Letterale stringa: variabile-stringa sequenza di caratteri racchiusa fra doppi apici; il compilatore trasforma un letterale stringa in un oggetto stringa, riferito da una variabile stringa anonima. Variabile stringa: può assumere come valore il riferimento di un letterale stringa: String s = "abc"; variabile anonima si hanno due azioni: s creazione di un oggetto stringa contenente "abc", riferito da una variabile anonima; assegnamento a s del valore della variabile anonima stringa 'a' 'b' 'c' G. Frosini Slide 20
STRINGHE (2) Creazione di un oggetto stringa: può avvenire anche utilizzando l operatore new, partendo da un letterale stringa, da un array di caratteri, o da un riferimento a un altro oggetto stringa, nel seguente modo: char[] aa = { '1', '2' ; String s1 = new String("de"); String s2 = new String(aa); String s3 = new String(s1); s1 'd' 'e' s2 '1' '2' s3 'd' 'e' G. Frosini Slide 21
CONCATENAZIONE DI STRINGHE Operatore di concatenazione + : se i due operandi sono riferimenti di oggetti stringa, l operatore produce il riferimento di un nuovo oggetto stringa che memorizza una nuova stringa ottenuta per concatenazione. se un solo operando è un riferimento di oggetto stringa e l altro di un tipo primitivo, quest ultimo viene preliminarmente convertito (da apposite funzioni della classe String) in un riferimento che indirizza un nuovo oggetto stringa. Esempi: "abc" + "de" stringa risultato: "abcde" 3 + 2 + "abc" stringa risultato: "5abc" "abc" + 3 + 2 stringa risultato: "abc32" "abc" + b (b boolean di valore true) stringa risultato: "abctrue" G. Frosini Slide 22
CONVERSIONE IN STRINGHE Classe String: contiene funzioni (metodi statici) per trasformare in riferimenti, contenenti indirizzi di oggetti stringa, valori di un tipo primitivo o di un riferimento di un array di caratteri: String String.valueOf ( boolean b ) String String.valueOf ( int i ) String String.valueOf ( long l ) String String.valueOf ( char c ) String String.valueOf ( float f ) String String.valueOf ( double d ) String String.valueOf ( char[] ac ) Applicazione dell operatore di concatenazione: String s = "Risultati: "; int i = 10; double d = 15.5; Console.scriviStringa(s + i + '\t' + d); In uscita: Risultati: 10 15.5 G. Frosini Slide 23
ALTRE OPERAZIONI SULLE STRINGHE Assegnamento: avviene fra variabili stringa, anche anonime, e quindi tra riferimenti (e non fra oggetti stringa): String s1 = s; le due variabili stringa s e s1 contengono adesso l indirizzo dello stesso oggetto stringa. Uguaglianza (operatori == e!=) confronta il valore di variabili stringa, e quindi di riferimenti (e non di oggetti stringa). Confronto fra due oggetti stringa: ottenuta applicando la funzione compareto() (con un argomento stringa) a una variabile stringa (sia actualstring) (risultato: negativo se <, zero se =, positivo se >): int actualstring.compareto( String s ) Lunghezza di una stringa: restituita dalla funzione length() applicata a una variabile stringa (sia actualstring): int actualstring.length() Selezione di un carattere: ottenuta applicando la funzione charat() (con un argomento intero (indice) che va da 0 alla lunghezza - 1) a una variabile stringa (sia actualstring): char actualstring.charat(int indice) G. Frosini Slide 24
ARRAY DI CARATTERI E STRINGHE Array di caratteri: sono oggetti costanti in dimensione, ma di contenuto variabile. Stringhe: Sono oggetti costanti (che contengono stringhe costanti). Raffronto: array di caratteri e stringhe sono di tipo diverso; come visto, si può creare una stringa a partire da un array di caratteri, o trasformare in una stringa un array di caratteri; esempio: char[] ac; String s1, s2; s1 = new String(ac); s2 = String.valueOf(ac); si può anche creare un array di caratteri partendo da una stringa, con la seguente funzione della classse String: char[] actualstring.tochararray() esempio: ac = s.tochararray(); Osservazione: non esiste un tipo Array, che dovrebbe specificare il tipo di elementi. G. Frosini Slide 25
ORDINAMENTO DI UN ARRAY DI STRINGHE (1) public class OrdinaS { static void sorts(string[] v) { boolean ordinato; int i; String t; do { ordinato = true; vetts[i] for (i = 0; i < v.length-1; i++) vetts[i+1] if (v[i].compareto(v[i+1]) > 0) { ordinato = false; t = v[i+1]; v[i+1] = v[i]; v[i] = t; while (!ordinato); Vengono scambiati i riferimenti public static void main(string[] args) { int i; String[] vetts = new String[8]; Console.scriviStringa("Scrivi 8 stringhe"); for (i=0; i<vetts.length; i++) vetts[i] = Console.leggiStringa(); sorts(vetts); for (i=0; i<vetts.length; i++) Console.scriviStr(vettS[i]); Console.nuovaLinea(); G. Frosini Slide 26
ORDINAMENTO DI UN ARRAY DI STRINGHE (2) public class OrdinaSS { static boolean maggiore(string a, String b) { int i, lun; if(a.length() < b.length()) lun = a.length(); else lun = b.length(); for(i=0; i<lun;i++) if (a.charat(i)!= b.charat(i)) break; if ((i==lun && a.length()>b.length()) (i<lun && a.charat(i)>b.charat(i))) return true; return false; static void sorts(string[] v) { boolean ordinato; int i; String t; do { ordinato = true; for (i = 0; i < v.length-1; i++) if (maggiore(v[i],v[i+1])) { ordinato = false; t = v[i+1]; v[i+1] = v[i]; v[i] = t; while (!ordinato); public static void main(string[] args) { int i; String[] vetts = new String[8]; Console.scriviStringa("Scrivi 8 stringhe"); for (i=0; i<vetts.length; i++) vetts[i] = Console.leggiStringa(); sorts(vetts); for (i=0; i<vetts.length; i++) Console.scriviStr(vettS[i]); Console.nuovaLinea(); G. Frosini Slide 27