Laboratorio 07 - 26/11/2020 - ESERCIZI ====================================== ------ Argomenti ------ - mappe (dizionari) - uso di mappe per problemi di conteggio - array bidimensionali - slice - os.Args - operazioni su slice con append, copy e subslicing ------ HowTo ------ dichiarazione di una map: sintassi: var map1 map[keytype]valuetype es: var map1 map[string]int allocazione(creazione)/inizializzazione di una map sintassi: map1 := make(map[keytype]valuetype) o anche: map1 := map[keytype]valuetype{} // tra {} ci può essere una lista di coppie chiave-valore es: map1 := make(map[string]float64) o anche: map1 := map[string]float64{} map1 := map[string]float64{"zero" : 0., "uno" : 1.} } dichiarazione di una slice: sintassi: var slice []type es: var slice []int allocazione(creazione)/inizializzazione di una slice sintassi: slice := make([]type, length, capacity) slice := make([]type, length) //la capacità può non essere specificata slice := []type{} // tra {} ci può essere una lista di valori es: slice := make([]int, 0, 5) slice := []int{} slice := []int{1, 2, 3, 4} differenza tra new e make: new(T) alloca memoria per un nuovo elemento di tipo T e restituisce il suo indirizzo, quindi un valore di tipo *T (un puntatore) e make(T) restituisce un valore di tipo T; si applica solo ai tipi riferimento predefiniti: slice, mappe (e canali). In altre parole, new alloca, make inizializza Funzioni built-in per slice (vedi documentazione packages, sotto builtin) - func append(slice []Type, elems ...Type) []Type es: slice = append(slice, elem1, elem2) slice = append(slice, anotherSlice...) - func copy(dest, src []Type) int _______________________________________ --- ESERCIZI --- _______________________________________ NumToText ========= # mappe - costruzione e uso Scrivere un programma num2text.go per convertire un numero intero non negativo nella sequenza delle parole corrispondenti alle sue cifre. Il programma legge un intero non negativo da standard input, per ogni nuova (non incontrata finora) cifra del numero chiede il nome corrispondente (e alimenta un dizionario), e infine stampa la sequenza delle parole corrispondenti alle sue cifre. Ad esempio, per il numero 203, il programma stampa due - zero - tre Esempio di esecuzione --------------------- $ go run num2text.go un numero: 622 parola per 2 ? due parola per 6 ? sei sei - due - due _______________________________________ Vocali ====== #mappe - conteggio Scrivere un programma vocali.go che analizza un testo e conta le occorrenze delle vocali (sia minuscole che maiuscole, ma non le accentate) nel testo e stampa, ma solo per le vocali presenti nel testo, il numero di volte che le vocali stesse sono presenti nel testo. In particolare il programma è dotato di: - una funzione func contaVocali(s string, vocali map[rune]int) per contare le occorrenze delle diverse vocali (sia minuscole che maiuscole - vedi es sotto) in tutte le stringhe che le vengono passate. La funzione, data una stringa s e una mappa vocali, aggiorna opportunamente la mappa vocali aggiungendo eventuali vocali non ancora presenti / incrementandone i valori. Per individuare le vocali e aggiornare la variabile vocali usate uno switch con un solo case o un if, sempre con un solo caso. Domande ------- Se invoco su diverse stringhe, quindi più volte, una funzione con questo prototipo: func contaVocali(s string, mappa map[rune]int) che incrementa, per ogni runa incontrata in s che mi interessa, il suo conteggio (mappa), la variabile mappa alla fine conterrà i dati: - della prima stringa che le è stata passata, - dell'ultima stringa che le è stata passata, - cumulativi di tutte le stringhe che le sono state passate - altro Perché? - una funzione func main() che legge una riga di testo da standard input e produce una mappa tra vocali presenti nel testo e il numero delle loro occorrenze nel testo, e la stampa. Esempio ------- se l'input è: jdhkas c'è dkasjhkdjashkdh askdh ksah @@@ €€€ ### Ħ wi) Ø qwqwe qwyewquteuqwte q 312312 2312wweqe €łłŧŧŧŧŧ sdasdas AA JKJLKLJLKJ LIIIIII u ù aeiou AEIO l'output è (salvo l'ordine di stampa): o : 1 E : 1 u : 4 e : 7 A : 3 I : 7 O : 1 a : 8 i : 2 Come si potrebbero stampare le vocali con le loro occorrenze in ordine alfabetico? Scrivere una seconda versione vocali_bis.go che produce l'output in ordine: A : 3 E : 1 I : 7 O : 1 a : 8 e : 7 i : 2 o : 1 u : 4 _______________________________________ Anagrammi ========= Scrivere un programma anagrammi.go che legge due stringhe da linea di comando e valuta se le due stringhe sono una l'anagramma dell'altra. In particolare il programma è dotato di: - una funzione func isAnagram(s1, s2 string) bool che restituisce true se le due stringhe sono una l'anagramma dell'altra, false altrimenti Domande: che caratteristiche ha un anagramma? c'è in Go una struttura di dati (array, struct, slice, map) che si presta a rappresentare i dati di una stringa s1 che servono ad individuare se è un anagramma di un'altra stringa s2? Se sì, quale e coma la uso? Se no, come imposto la soluzione? - una funzione func main() che legge due parole p1 e p2 da linea di comando e stampa uno dei due messaggi: p1 e p2 sono anagrammi p1 e p2 non sono anagrammi In assenza di esattamente due parametri sulla linea di comando il programma stampa: input errato _______________________________________ Galleggianti ============= #matrice (slice bidimensionale) Scrivete un programma galleggianti.go che legga da standard input due interi r, c, seguiti da una matrice di r righe e c colonne contenente lettere maiuscole e asterischi, e che stampi in output la matrice che si ottiene da quella in input mandando verso il basso le lettere e facendo galleggiare gli asterischi. Fornire l'input una riga della matrice alla volta, sfruttando la funzione strings.Split(s, " ") (vedi documentazione). Si assuma che ogni riga di input contenga esattamente c caratteri, separati da spazi. Esempio ------- Se la matrice è data da V * S * * B K * * * S * il programma dovrà stampare la matrice seguente: * * * * * * V * S K S B _______________________________________ Operazioni su slice =================== Scrivere un programma operazioni_slice.go che fa, una alla volta, le seguenti operazioni su slice, stampando poi il risultato ottenuto. Date voi dei valori opportuni alle variabili (slice, i, j, ...) - crea due slice a e b che contengono degli interi (date voi dei valori direttamente nel programma) - appende la seconda alla prima e stampa la slice risultante - crea una nuova slice b e vi copia a - cancella l'elemento di indice i dalla slice a - cancella gli elementi da i a j dalla slice a - estende la slice a con una nuova slice di lunghezza j - inserisce l'elemento x in posizione i - inserisce una nuova slice di lunghezza j in posizione i - inserisce la slice b in posizione i - estrae, cancellandolo dalla slice (pop) l'ultimo elemento della slice a - aggiunge alla fine della slice a un nuovo elemento x (push) _______________________________________ Appello ------- #slice (os.Args) Scrivere un programma appello.go che legge da linea di comando una sequenza di nomi e li stampa in ordine alfabetico. Esempio _______ $ go run appello.go Rita Carlo Matteo Ada [Ada Carlo Matteo Rita] Nota: Utilizzare la funzione Strings(a []string) del pacchetto "sort" per ordinare in modo crescente i nomi. _______________________________________ Stats temperature ----------------- #slice Scrivere un programma temperature.go che legge delle temperature (int) da tastiera e termina quando il valore letto è 999. Il programma deve stampare - la media - la mediana - il numero di temperature sotto la media delle temperature stesse. - le tre temperature più basse (se ci sono almeno 3 temperature) - le tre temperature più alte (se ci sono almeno 3 temperature) Nota 1: la mediana di un insieme di dati e` data, nel caso ci sia un numero dispari di dati, dal dato centrale dei dati ordinati per valore (ad es. crescente), altrimenti dalla media dei due dati centrali. Nota 2: Utilizzare la funzione Ints(a []int) del pacchetto "sort" per ordinare in modo crescente le temperature. __________________________________________________________ Posizioni parole ================ Scrivere un programma posizioni_parole.go che legge una sequenza di stringhe da standard input e produce su standard output, per ogni stringa, la lista delle posizioni in cui essa compare nella sequenza (partendo dalla posizione 0) Nota: per terminare l’input da tastiera, premere invio e la combinazione di tasti Ctrl D, che corrisponde a EOF (end of file) per lo standard input. In caso di dubbi su come gestire la fine dell’input nel programma, consultare la documentazione della funzione Scan, funzione che, oltre a salvare i valori letti, restituisce dei valori. Esempio: -------- $ go run posizioni_parole.go scrivi parole (ctrl D per terminare) O bella ciao bella ciao bella ciao ciao ciao Una mattina mi sono alzato map[O:[0] Una:[9] alzato:[13] bella:[1 3 5] ciao:[2 4 6 7 8] mattina:[10] mi:[11] sono:[12]] __________________________________________________________