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