|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Member
Iscritto dal: Jan 2010
Messaggi: 34
|
[C] Alberi binari, datemi un mano a capire una piccola porzione di codice.
Codice:
Albero LeggiAlberoFD(FILE *fd) {
Albero a;
int res, x;
char c;
/* legge la parentesi ( */
res=fscanf(fd, "%c", &c);
if(res!=1 || c!='(') {
ungetc(c, fd);
return NULL;
}
/* legge l'intero oppure ) */
res=fscanf(fd, "%c", &c);
if(res!=1 || c==')')
return NULL;
ungetc(c, fd);
fscanf(fd, "%d", &x);
/* crea il nodo */
a=malloc(sizeof(struct NodoAlbero));
a->radice=x;
a->sinistro=LeggiAlberoFD(fd);
a->destro=LeggiAlberoFD(fd);
/* legge ) */
fscanf(fd, "%c", &c);
return a;
}
Come funziona in questo caso? Poi non capisco il secondo fscanf: come fa a memorizzare il secondo carattere senza chiamare prima la funzione ungetc(c, fd), che avanza al carattere successivo? Per il resto è tutto chiaro. Grazie per l'aiuto |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: May 2014
Messaggi: 1370
|
L'algoritmo è più o meno questo:
1) Leggi con fscanf un carattere dal file fd 2) Se la fscanf non riesce a leggere un carattere oppure il carattere letto non è '(' allora la funzione "rimette a posto" il carattere c nel file fd con la ungetc e termina restituendo NULL (in questo caso quindi la lista non è nel formato corretto) 3) Con la seconda fscanf leggi un altro carattere 4) Se la seconda fscanf non riesce a leggere un carattere o il carattere letto è ')' allora la funzione termina restituendo NULL (in questo caso se sei al primo livello di ricorsione la lista è vuota cioè hai solo la parentesi aperta e chiusa perciò la radice dell'albero deve essere NULL mentre se sei nei livelli successivi di ricorsione hai finito la lista e quindi restituisci NULL perchè non ci sono più valori da allocare nei nodi) 5) Se arrivi qui, un carattere è stato letto e non è ')' perciò deve essere un intero. Di conseguenza va rimesso a posto il carattere già letto dalla seconda fscanf e riletto con una terza fascanf come numero e messo in x 6) Crei un nodo in cui salvare il valore x 7) Chiami ricorsivamente la funzione (prima per costruire il sottoalbero a sinistra e poi a destra) 8) Alla fine leggi l'ultimo carattere che sarà ')' e poi la funzione restituisce a Un consiglio personale: per capire come funziona una funzione ricorsiva basta prendere un esempio di stringa valida e analizzare uno alla volta i vari livelli della ricorsione. Io di solito lo facevo a mano perchè mi aiutava a ragionare. Ultima modifica di monte.cristo : 19-11-2014 alle 15:11. |
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
|
E' da notare che se la fscanf fallisce, il contenuto di c e' indeterminato; pertanto andrai ad inserire un valore indeterminato nel buffer dello stream di ingresso, che presumibilmente utilizzerai con scarso profitto da qualche altra parte del codice (altrimenti non ti saresti premurato in reinserirlo, giusto?)
__________________
In God we trust; all others bring data |
|
|
|
|
|
#4 |
|
Member
Iscritto dal: Jan 2010
Messaggi: 34
|
ti ringrazio molto per l'aiuto, sei stato illuminante!
|
|
|
|
|
|
#5 |
|
Member
Iscritto dal: Jan 2010
Messaggi: 34
|
Grazie a tutti voi per l'aiuto! con l'algoritmo espresso in linguaggio formale ora mi è molto più chiaro!
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 06:11.




















