procedure delete_el_it(var l:list; e:elemtype); {AF: elimina la prima occorrenza di 'e' in 'l', vers. iterativa} var p,t:list; trov:boolean; begin trov:=false; t:=l; p:=l; {t e` per non perdere la testa della lista, p servira` per puntare all'el. prec. a quello puntato da t} while (t<>nil) and (not trov) do begin if t^.elem=e then begin trov:=true; if p=t then l:=l^.next {nel caso primo el. devo mod. 'l'} else p^.next:=t^.next; end; p:=t; t:=t^.next; end end; procedure delete_el_ric(var l:list; p:list; e:elemtype); {AF: elimina la prima occorrenza di 'e' in 'l', vers. ricorsiva} 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;La 'delete_el_ric' ha un parametro in piu' rispetto alla 'delete_el_it', il parametro 'p'. Esso ha la stessa funzione della variabile locale 'p' della versione iterativa, ovvero quella di puntare all'elemento precedente all'elemento puntato da 'l' (puntato da 't' nella versione iterativa). Dal main, se per esempio 'lis' e`una lista dalla quale vogliamo cancellare '5', chiameremo la 'delete_el_ric' con: delete_el_ric(lis,lis,5).
function length(l:list):integer; {AF: restituisce il numero degli elementi di 'l'} begin if l=nil then length:=0 else length:=1+length(l^.next) end; procedure delete(var l:list; i:integer); {AF: cancella l'elemento di posizione i-esima in 'l'} var p,t:list; cont:integer; begin if (0>=i) OR (i>length(l)) then writeln('errore...') else begin if i=1 then l:=l^.next else begin t:=l^.next; p:=l; {t e` per non perdere la testa della lista, p punta all'el. prec. a quello puntato da t} cont:=2; while i>cont do begin cont:=cont+1; p:=t; t:=t^.next end; p^.next:=t^.next; end end end; procedure search(l:list; i:integer; var e:elemtype); {AF: restituisce in 'e' l'elemento i-esimo} {Fatta come funzione sarebbe piu' elegante, ma piu' difficile segnalare la condizione di errore} var pos:integer; begin if (0>=i) OR (i>length(l)) then writeln('errore...') else begin for pos:=1 to i-1 do l:=l^.next; e:=l^.elem end end;Notate l'uso del parametro 'e': e` proprio in 'e' che mettiamo il risultato della nostra ricerca, ovvero l''elem' i-esimo.
- Provate a proporre una soluzione alternativa alla 'delete_el_it' che sia piu' elegante/semplice/efficiente/etc.
- Scrivete una procedura che sia una modifica della 'delete_el_it' (e/o della 'delete_el_ric') che cancelli TUTTE le occorenze di 'e' in 'l'.
- Modificate la 'cerca_el' presentata nella lezione del 2/2/2001 e riproposta qui sotto, in modo che restituisca la posizione dell'elemento 'e' in 'l', se 'e' appartiene a 'l', invece di un booleano.
function cerca_el(l:list; e:elemtype):bool; {AF: restituisce TRUE se l'elemento 'e' appartiene alla lista 'l', FALSE altrimenti} begin if (l=nil) then cerca_el:=false else if (l^.elem=e) then cerca_el:=true else cerca_el:=cerca_el(l^.next, e); end;
- Data una lista di interi e una di booleani della stessa lunghezza, modificare la prima nel seguente modo: se nell'elemento di posizione 'i' nella lista di booleani c'e` TRUE, cancellare il corrispondente i-esimo elemento nella lista degli interi. ESEMPIO: L1 = 1,2,3,4, L2 = T,F,F,T ==> L1 diventa L1 = 2,3.
- Scrivete una procedura che, date due liste L1 e L2 di interi, produca una terza lista L3 che contenga come elementi la somma degli elementi di posizione corrispondente nelle liste in input. Se una delle due liste in input e` piu' lunga, gli elementi in sovrappiu' andranno copiati cosi' come sono nella lista ouput L3. ESEMPIO: L1 = 1,2, L2 = 3,4,5 ==> L3 = 4,6,5.
Soluzioni (Non ancora presenti)