procedure insert(var l:list; e:elemtype; i:integer); {AF: inserisce l'elemento 'e' in 'l' alla posizione i-esima} var p,t:list; j:integer; begin if (0>=i) OR (i>length(l)+1) then writeln('errore...') else begin if i=1 then {inserzione in testa!!!} begin new(p); {(1)} p^.elem:=e; p^.next:=l; l:=p; {da (1) a qui e` in pratica una 'cons(e,l)'} end else begin j:=1; t:=l; while i-1>j do begin t:=t^.next; j:=j+1; end; new(p); p^.elem:=e; p^.next:=t^.next; t^.next:=p end end end;
procedure delete_el_ric(var l:list; p:list; e:elemtype); {AF: elimina la prima occorrenza di 'e' in 'l', vers. ricorsiva} {VISTA IL 9/2/2001} begin if l<>nil then begin if l^.elem=e then if p=l then l:=l^.next else p^.next:=l^.next else delete_el_ric(l^.next, l, e) end end; procedure delete_el_ric2(var l:list; p:list; e:elemtype); {AF: cancella TUTTE le occorrenze di 'e' in 'l', versione ricorsiva} {VISTA DURANTE LA LEZIONE DI OGGI} begin if l<>nil then begin if l^.elem=e then if p=l then begin l:=l^.next; delete_el_ric2(l, l, e) end else begin p^.next:=l^.next; delete_el_ric2(p^.next, p, e) end else delete_el_ric2(l^.next, l, e) end end;
Una proposta di soluzione (senza controlli sugli errori, per cui da completare, se volete) per l'esercizio:
type famiglia = record nomepadre,nome: char end; max=100; type arrfam = array [1..max] of famiglia;scrivere una procedura (o funzione, scegliete voi la piu' adatta) ricorsiva che, dato un parametro 'nm' di tipo carattere rappresentante un nome, e un intero 'a', ritrovi l'a-esimo antenato di 'nm' (con la convenzione che a=1 richiede di trovare il padre di 'nm', a=2 il nonno, etc). Ad esempio, se nell'array abbiamo |c.p|b.c|k.b|f.g|, e nm=p e a=2, l'output deve essere 'b' (ovvero il padre del padre di p). Ovviamente questa procedura/funzione dovra` essere opportunamente inserita in una unit che permetta anche l'inserimento e la stampa dell'array. Inoltre, cercate di prevedere tutti i possibili casi in cui la procedura/funzione potrebbe dare errore, e trattate questi casi di conseguenza.
function trovanome(cnome:char):integer var i:integer; {ASSUMIAMO che l'array 'par' di tipo 'arrfam' e la sua dimensione 'n' siano GLOBALI. Quello che interessa QUI e` capire come sviluppare il punto centrale del problema. Le eventuali migliorie rispetto a buone regole di programmazione, efficienza, etc, possono essere realizzate dopo...} begin for i:= 1 to n do if (par[i].nome=cnome) then trovanome:=i; end; function antenato(c:char; a:integer; cont:integer):char var pos:integer; {ASSUMIAMO che l'array 'par' di tipo 'arrfam' e la sua dimensione 'n' siano GLOBALI. Quello che interessa QUI e` capire come sviluppare il punto centrale del problema. Le eventuali migliorie rispetto a buone regole di programmazione, efficienza, etc, possono essere realizzate dopo...} begin pos:=trovanome(c); if (cont=a) then antenato:=par[pos].nomepadre else antenato:=antenato(par[pos].nomepadre, a, cont+1) end; ... begin {main} ... {l'array 'par' di tipo 'arrfam' viene opportunamente riempito} ... {siano 'cnome' e 'ant' inizializzate con un carattere e un numero:} anten:=antenato(cnome, ant, 1); {'anten', che va` dichiarato come carattere, conterra` l'antenato numero 'ant' di 'cnome'. Naturalmente, modulo eventuali errori che possono accadere, ad esempio se l'array 'par' non contenesse la catena ereditaria completa richiesta, o, come caso particolare del problema precedente, se 'cnome' non appartenesse a 'par', etc, etc. Ripeto, pensate voi a completare opportunamente l'esercizio.} ... end.