ARRAY Ivan Lanese Argomenti • Array • Stringhe • Merge sort Array • E' una struttura dati che contiene più elementi dello stesso tipo • Normalmente su elementi diversi di uno stesso array si fanno operazioni simili – – Si usa un ciclo o una funzione ricorsiva Si usa un indice per individuare l'elemento specifico • Gli array hanno dimensione costante – Se la dimensione dell'array non è nota si usa una sovrastima • L'array dei voti di uno studente non supererà i 50 elementi Array: sintassi • Gli array vengono dichiarati come le altre variabili, specificando il numero di elementi (costante) – – int array[20]; const int n=30; int voti[n]; • Si accede ad un elemento di un array specificando l'indice dell'elemento – – – array[2]=5; voto[i]=27; cout << voto[i]; • Un array viene passato ad una funzione senza specificare il numero di elementi, che spesso è passato come parametro addizionale – – stampa(array, n); m=media(voti, n); Array: esercizi • Prendere in input numeri interi fino a quando l'utente non inserisce uno 0. Stampare la sequenza inserita al contrario. • Prendere in input 10 numeri e stampare i prodotti di tutte le coppie – Se i numeri fossero 1, 2, ... 10 si otterrebbe la tabella delle tabelline • Scrivere una funzione che dato un numero binario lo converte in decimale • Scrivere una funzione che elimina tutti i duplicati da un array di interi Stringhe • Le stringhe sono particolari array di caratteri • La lunghezza effettiva di una stringa è uno più del numero di caratteri significativi che contiene – Dopo l'ultimo carattere significativo, c'è il carattere speciale '\0' usato come terminatore – La stringa “CIAO” è composta da 5 caratteri: 'C' 'I' 'A' 'O' '\0' • Una stringa deve essere contenuta in un array di caratteri di dimensione sufficiente – – Si usa una sovrastima, come per gli altri array Fare attenzione a non uscire dalla dimensione dell'array, in particolare effettuando l'input • Il buffer overflow è una nota tecnica di attacco hacker Lavorare con le stringhe • Ci sono 2 modi per lavorare con le stringhe – A basso livello, trattandole come array di caratteri – Ad alto livello, usando le funzioni predefinite che lavorano sulle stringhe • A basso livello – Si elaborano i caratteri uno alla volta – Quando si passa una stringa a una funzione, spesso non è necessario passarne la lunghezza • E' sufficiente usare la posizione del '\0' • Questo non vale quando è necessario estendere la stringa Stringhe viste come array di caratteri: esercizi • Scrivere una funzione che verifica se una stringa è palindroma • Scrivere una funzione che calcola la lunghezza di una stringa • Scrivere una funzione che copia una stringa in un array di caratteri dato • Scrivere una funzione che concatena due stringhe • Scrivere una funzione che elimina da una stringa tutti i caratteri dopo l'ennesimo Stringhe: funzioni di libreria • E' possibile prendere in input stringhe con >> e stamparle con << • Il c++ fornisce diverse funzioni di libreria per manipolare le stringhe – Occorre includere <cstring> • Gli esercizi 2, 3, 4 di prima corrispondono alle funzioni strlen, strcpy e strcat – – – int strlen(char []); void strcpy(char [], char []); void strcat(char [], char []); • Gli operatori relazionali non funzionano sulle stringhe, per scrivere s1<s2 devo scrivere strcmp(s1,s2)<0 – int strcmp(char [], char []); Stringhe: esercizi • Scrivere un programma che date tre stringhe stampa la più lunga • Scrivere un programma che dati due nomi stampa il primo in ordine alfabetico Ordinamenti • Gli ordinamenti sono una parte fondamentale di molti programmi – – Perchè richiesto dalla specifica Per migliorarne la complessità • Cfr. esercizio sull'eliminazione dei duplicati • Esistono molti algoritmi di ordinamento, con caratteristiche diverse – – E' molto interessante la complessità, cioè come cambia il tempo di esecuzione alla variazione della dimensione dell'input Ordinamentio buoni hanno complessità che cresce come n log n Merge sort • E' un algoritmo di ordinamento ricorsivo, con complessità n log n • Casi base: un array di 0 o 1 elemento è ordinato • Caso induttivo: dividere l'array in 2 metà, ordinarle tramite chiamate ricorsive e poi farne la fusione ordinata Mergesort void mergesort(int a[],int p,int r) { int q; if (p<r) { q=(p+r)/2; mergesort(a,p,q); mergesort(a,q+1,r); merge(a,p,q,r); } } Merge void merge(int a[], int p, int q, int r) { int i, j, k, h, b[length]; i=p; k=p; j=q+1; while(i<=q && j<=r) { if(a[i]<=a[j]) { b[k]=a[i]; i=i+1; } else { b[k]=a[j]; j=j+1; } k=k+1; } if (i<=q) { for(h=q;h>=i;h=h­1) a[h+r­q]=a[h]; } for(j=p;j<k;j=j+1) a[j]=b[j]; }