Progetto per il Corso di Algoritmi e Strutture Dati
Transcript
Progetto per il Corso di Algoritmi e Strutture Dati
Progetto per il Corso di Algoritmi e Strutture Dati Docente Dott. Gianluca Rossi 11 Novembre 2004 1 Obiettivo del Progetto Scopo del progetto è l’implementazione delle strutture dati e degli algoritmi per la gestione dei sistemi di scrittura intuitiva di testo con tastiere numeriche (T9). 2 Introduzione e Definizioni Preliminari Un dizionario di parole D in un alfabeto X = {x1 , . . . , xk } di k simboli può essere rappresentato in memoria con una struttura dati ad albero diretto k-ario con radice r in cui ogni cammino nell’albero rappresenta un prefisso valido ovvero una stringa che compare come prefisso di almeno una parola del dizionario D. • Ogni nodo dell’albero ha al più k figli (tanti quanti sono i caratteri dell’alfabeto) connessi dagli archi e(x1 ), . . . , e(xk ). • Ad ogni arco è associato un carattere dell’alfabeto. In questo modo, ad ogni cammino dalla radice ad un nodo dell’albero è possibile associare una stringa nell’alfabeto X ovvero al cammino e(x01 )e(x02 ) . . . e(x0h ) si associa la stringa x01 x02 . . . x0h . • Si vuole che, per ogni cammino dell’albero, la stringa associata ad esso sia un prefisso valido. Notare che se due parole del dizionario hanno una parte iniziale comune allora i due cammini che codificano le due parole hanno un sottocammino comune della lunghezza della sequenza comune. Inoltre, dalla definizione, segue che ad ogni cammino radice-foglia corrisponde una parola del dizionario. Comunque vi possono essere parole del dizionario che sono associate a cammini terminanti in nodi interni dell’albero. Questo accade se una parola del dizionario è prefisso di un’altra. Per questo motivo è opportuno assegnare etichette particolari a quei nodi che sono i punti terminali di un cammino associabile ad una parola del dizionario. 1 Esempio: Di seguito è illustrato l’albero che codifica il dizionario D = {arte, arto, atto, attore, oro, orto} con alfabeto X = {a, e, o, r, t}. r e(a) e(o) e(r) e(o) e(r) e(t) e(t) e(t) e(t) e(o) e(e) e(o) e(o) e(r) e(e) Figura 1 I nodi bianchi rappresentano la fine dei cammini che codificano parole del dizionario. Si osservi che tutte le foglie sono bianche e che l’unico nodo interno bianco è quello associato al cammino che codifica la parola atto che è una sottostringa della parola attore. 2.1 Operazioni Fondamentali Si definiscono due operazioni fondamentali: • Ricerca: Data una stringa w nell’alfabeto X, si vuole verificare se w appartiene al dizionario. • Inserimento: Data una parola w 6∈ D si vuole inserire w in D. 2.1.1 Ricerca Sia w = c1 c2 . . . ct con ci ∈ X la parola da ricercare: Si scandisce la stringa w carattere per carattere partendo dal primo (c1 ) e ad ogni passo i si verifica se esiste il cammino c1 . . . ci . In particolare, per i = 1 si verifica che esista l’arco e(c1 ) che esce dalla radice. Al passo generico i, assumendo che esista il cammino e(c1 ) . . . e(ci−1 ) che termina nel nodo v, si verifica se esiste l’arco e(ci ) uscente da v. Esempio: Consideriamo il dizionario raffigurato in Figura 1, vogliamo verificare se la stringa arto è presente nel dizionario. 1. Si parte leggendo il carattere a e si verifica se dalla radice r esce l’arco e(a); 2. Poiché questo esiste ci si sposta sul nodo che viene connesso a r tramite e(a) e si verifica se esiste l’arco e(r) uscente da questo nodo; 3. Ancora una volta la risposta è positiva. Si passa al nodo puntato dall’arco e(r) e si verifica se da questo nodo parte l’arco e(t); 4. L’arco e(t) esiste quindi seguiamo questo arco fino ad arrivare ad un nuovo nodo; 5. Dal nuovo nodo parte l’arco e(o) che giunge ad un nodo bianco quindi, poiché abbiamo letto tutti i caratteri della stringa e siamo giunti ad un nodo bianco, concludiamo che la parola arto è contenuta nel dizionario. 2 2.1.2 Inserimento Sia w = c1 c2 . . . ct con ci ∈ X la parola da inserire nel dizionario. Se w 6∈ D allora la ricerca di w nell’albero ad un certo punto fallisce. In particolare, applicando la procedura di ricerca, si giunge ad un nodo u dell’albero da cui non è più possibile andare avanti. La stringa corrispondente al cammino dalla radice a u è la più lunga sottostringa di w prefisso di qualche parola di D. Se c 1 . . . cj−1 è questa sottostringa, dobbiamo inserire il cammino e(cj )e(cj+1 ) . . . e(ct ) nell’albero a partire dal nodo u. Esempio: Inseriamo la parola ateo al dizionario di Figura 1. Prima verifichiamo che tale parola non è contenuta nel dizionario. Ci accorgiamo che non è contenuta leggendo il terzo carattere della stringa: Infatti la radice contiene l’arco uscente e(a), il nodo puntato dall’arco e(a) contiene l’arco uscente e(t) ma questo raggiunge un nodo che non contiene l’arco uscente e(e). Per inserire la parola si eseguono i seguenti passi a partire dal terzo carattere della parola e dal nodo u puntato da e(t). 1. Si crea un nuovo nodo e si collega u al nuovo nodo attraverso l’arco e(e) uscente da u; 2. Sia u il nuovo nodo creato: Si crea un nuovo nodo e si collega u al nuovo nodo attraverso l’arco e(o) uscente da u; 3. Sia u il nuovo nodo creato: Poiché abbiamo terminato l’inserimento della nuova stringa, coloriamo u di bianco. In Figura 2 è riportato il nuovo albero. r e(a) e(o) e(r) e(o) e(r) e(t) e(t) e(o) e(e) e(t) e(t) e(o) e(o) e(e) e(o) e(r) e(e) Figura 2 3 Il Sistema T9 Da quanto detto sopra, esiste una associazione uno-a-uno tra archi uscenti da un nodo e caratteri dell’alfabeto. Questo vincolo può essere rilassato associando ad ogni arco un insieme di caratteri. Quindi un cammino può essere associato ad un insieme di stringhe. Questo è quello che succede nella codifica dei caratteri alfabetici con i caratteri numerici da 2 a 9 utilizzata per esempio nei telefoni cellulari per scrivere SMS. L’associazione standard tasto numerico - carattere è ripostata nella seguente tabella. 3 2 3 4 5 6 7 8 9 abc def ghi jkl mno pqrs tuv wxyz Tabella 1 Codificando stringhe con numeri si ha che ad una stessa sequenza di numeri possono corrispondere più stringe del dizionario. Per esempio alla sequenza 22776 sono associate le parole basso, carro, capro. Se la sequenza numerica rappresenta il cammino nell’albero che codifica il dizionario allora ad un cammino possono essere associate più parole del dizionario. Queste parole possono essere memorizzate nel nodo terminale del cammino. In particolare nell’esempio precedente, il cammino associato alla sequenza 22776 terminerà in un nodo che contiene la lista di parole basso, carro e capro. 3.1 Il Progetto Si richiede che lo studente implementi nel linguaggio C un progetto che gestisce operazioni di inserimento e ricerca di parole all’interno di un dizionazio nell’alfabero X = {a, b, . . . , y, z} codificato con i caratteri numerici come descritto in Tabella 1. Le operazioni di inserimento e ricerca devono generalizzare quelle descritte nella sezione precedente. L’inserimento e la ricerca di una parola di lunghezza t deve richiedere O(t + h) passi dove h è il numero di parole del dizionario che hanno la stessa codifica della parola da inserire. Il programma creato dallo studente deve: 1. Prendere dalla linea di comando un file contenente una lista di parole che costituirà il dizionario alfabetico iniziale; 2. Inserire nel dizionario (che all’inizio sarà vuoto) tutte le parole contenute nel file; 3. Entrare in una fase interattiva in cui l’utente può decidere di effettuare una ricerca oppure un inserimento: • L’utente esegue una ricerca digitando una sequenza numerica di caratteri da 2 a 9. Il programma restituisce la lista di parole nel dizionario che hanno come codifica la sequenza numerica inserita; • Nell’inserimento l’utente digita la stringa alfabetica che il programma converitirà nel corretto codice numerico e provvederà ad aggiornare la struttura dati. La fase di inserimento si conclude aggiungendo la parola inserita nel file dato in input. La fine della fase iterativa è decisa dall’utente. 3.2 Modalità di Consegna del Progetto Il progetto deve essere costituito da uno o più file contenenti il codice C del progetto opportunamente commentati. Nel caso di più file da compilare si richiede la consegna di un opportuno makefile. Unitamente alla consegna dei file sorgente va consegnata una breve relazione (non più di 4 pagine) che descriva la modalità di compilazione, il manuale utente e le strutture dati implementate con i relativi algoritmi di gestione. Qualora una soltanto delle direttive su indicate non venga rispettata il progetto non sarà considerato sufficiente. Il progetto è individuale. Un progetto consegnato da più persone non sarà valutato. I termini della consegna verranno decisi quando saranno note le date degli appelli della sessione invernale (comunque non prima del 6/1/2005). 4