Albero genealogico
Si abbia un albero genealogico come nella figura sotto. Si supponga che i nomi propri delle persone siano tutti diversi, e quindi sufficienti a caratterizzare le persone stesse. I nomi siano lunghi al più 15 caratteri. Descrivere una organizzazione dei dati atta a descrivere i rapporti di parentela. In particolare si richiede un programma in C che permetta di creare, aggiornare e interrogare la base dati secondo le seguenti specifiche:
- Se da terminale si introduce la stringa I nome1 nome2 si richiede di aggiornare la base dati inserendo la persona nome1 come figlio di nome2. Eccetto che per la prima richiesta, in cui bisogna inserire sia nome2 (progenitore) che nome1 (figli), in tutti gli altri casi occorre segnalare errore se nome1 esiste già, ed analogamente se non esiste nome2.
- Se da terminale si introduce la stringa D nome1 nome2 si richiede di verificare se c'è discendenza diretta tra la persona nome1 e la persona nome2. Se c'è discendenza diretta, è richiesta la stampa dei nomi delle persone che costituiscono quel ramo. Si supponga di non sapere a priori se nome1 è antecedente a nome2 o viceversa: pertanto è richiesto di verificare esiste_discendenza diretta(nome1, nome2) e esiste_discendenza_diretta(nome2, nome1) prima di dichiarare che non c'e' discendenza diretta.
ADAMO | | | CAINO ABELE | | | | | | ABRAMO ISACCO GIOSUE GABRIELE | | | | | | | | | GIUSEPPE SALVATORE ERNESTO | | | | | | | | | ESAU' GIORGIO
SUGGERIMENTO: realizzare la base dati con un vettore di struct. Ciascuna struct contenga il nome della persona (stringa) e la posizione del padre (intero) all’interno del vettore. Per il progenitore si preveda come posizione del padre un valore impossibile, ad esempio -1 (tappo). Se ad esempio sono stati dati i seguenti tre comandi: I Caino Adamo I Abramo Caino I Abele Adamo la base dati dovrà apparire così (la prima colonna ovviamente non esiste, è stata disegnata per comodità e indica la numerazione degli elementi del vettore di struct): 0Adamo-1 1Caino0 2Abramo1 3Abele0
BASE DATI (globale): char nome1[LUNG_NOME], nome2[LUNG_NOME]; char comando; struct { char nome[LUNG_NOME]; int posizione_padre; } genealogico[MAX_NOMI]; int quanti_nomi; char sequenza[MAX_NOMI][LUNG_NOME];
Main Poni quanti_nomi a 0 Invia il prompt Inizializza comando con blank Finché il carattere letto in comando ‘F’ –leggi nome1 e nome2 –scelta su comando : è ‘I’ : inserisci (nome1, nome2) è ‘D’ : verifica_discendenza_diretta (nome1, nome2) default: segnala errore –leggi fino a new-line Fine.
Funzione inserisci (figlio, padre) Se quanti_nomi è 0 –in genealogico[0], nel campo nome, metti padre –in genealogico[0], nel campo posizione_padre, metti TAPPO –in genealogico[1], nel campo nome, metti figlio in genealogico[1], nel campo posizione_padre, metti 0 –poni quanti_nomi a 2 altrimenti
–Se presente (figlio, posizione) scrivi “Errore, figlio esiste già” –altrimenti se non presente (padre, posizione) –scrivi “Errore, padre non è stato ancora inserito” altrimenti –in genealogico[quanti_nomi], nel campo nome, metti figlio –in genealogico[quanti_nomi], nel campo posizione_padre, metti posizione –incrementa quanti_nomi Fine.
Funzione verifica_discendenza_diretta (progenitore, discendente) Se presente (progenitore, posizione) –se presente (discendente, posizione) Se esiste_discendenza_diretta (progenitore, discendente, quanti_passi) –stampa_discendenza(quanti_passi) altrimenti –Se esiste_discendenza_diretta (discendente, progenitore, quanti_passi) »stampa_discendenza(quanti_passi) –altrimenti »stampa “Non esiste discendenza diretta”
–altrimenti stampa “Errore : non esiste discendente” altrimenti –stampa “Errore : non esiste progenitore” Fine.
Funzione esiste_discendenza_diretta (progenitore, discendente, grado), tipo boolean Poni grado pari a 0 Poni provata_discendenza_diretta a Falso Poni flag_esiste pari a presente(discendente, posiz_discendente) \* cerca la posizione *\ Poni posiz-discendente in indice
Finché provata_discendenza_diretta è Falso AND predecessore TAPPO –poni il campo nome di genealogico[indice] in sequenza[grado] –incrementa grado –se il campo nome di genealogico[indice] = progenitore poni provata_discendenza_diretta a Vero –altrimenti poni il campo posizione_padre di genealogico[indice] ancora in indice Restituisci provata_discendenza_diretta Fine.
Funzione presente (nome_cercato, posizione), tipo boolean Poni indice a 0 Poni trovato a Falso Finché non trovato AND indice < quanti_nomi –se il campo nome di genealogico[indice] = nome_cercato poni trovato a Vero –altrimenti incrementa indice Poni posizione pari a indice Restituisci trovato Fine.