Classe 4 Bi             5-03-2001

 

Risolvere i seguenti problemi:

 

1.  Sia a1 un atomo contenente 1, a2 un atomo contenente 2, a3 contenente 3, a4 contenente 4, a5 un atomo contenente 5.
Scrivere come si realizzano due delle seguenti liste senza utilizzare la primitiva list:

     (1 2 3 4 )    -->  cons(a1, cons(a2, cons(a3, cons(a4, make_nil()))));

     ((1))         -->  cons(cons(a1,make_nil()),make_nil()));

 

     (( 1 2 3) 4 ) -->  cons(cons(a1, cons(a2,

                                 cons(a3,make_nil()))),make_nil());
     ( 1 2 3 (4 5))     -->  cons(a1, cons(a2, cons(a3, c
ons(

                            cons(a4, cons(a5, make_nil())),                                        make_nil())));

 

2.  Sia L una lista omogenea propria di caratteri. Scrivere una function che restituisce la lista  a partire da una determinata posizione p di L.

La posizione è determinata dal numero di caratteri precedenti. P sarà quindi un intero che indica il numero di caratteri. La funzione ha in ingresso la lista e un intero.

Se la lista è vuota allora restituisci la lista vuota.
Se p è uguale a zero allora restituisci la lista avuta in ingresso.(Non c'è nulla da fare!!)

altrimenti procedi eliminando il primo elemento della lista e decrementando p di 1.


sexpr ultimi( sexpr s, int p) {
     if( null(s) ) return s;
     if( p == 0) return s;
     return ultimi(cdr(s), p-1);
}

Le prime due condizioni si possono riscrivere così:

     if( (null(s)) || (p == 0)) return s;


3.  Scrivere una function che, avuto in ingresso una lista non omogenea, restituisce la media dei numeri interi positivi divisibili per 5.
 
La media aritmetica si calcola sommando tra loro tutti gli elementi che ci interessano dividendoli per la quantità di elementi sommati.
 
 int somma(sexpr l);
 int conta(sexpr l);
 
 float media( sexpr l) {
     if(conta(l) > 0)
         return (float)somma(l) / conta(l);
     return -1;
    
 Per sommare gli elementi:
 
 se la lista è vuota la somma è zero
 altrimenti
     se il primo elemento della lista è "buono" la somma è il primo elemento

                   + la somma dei rimanenti
     altrimenti la somma è uguale alla somma dei rimanenti.
    
 
int somma(sexpr l){
     if( null(l) ) return 0;
     if( buono(car(l)) )
         return *(int*)dato(car(l)) + somma( cdr(l) );
     return somma( cdr(l) );
 }
 
 int buono( sexpr a ) {
     return is_int(a) && (*(int*)dato(a)%5 == 0);
 }
 
 int conta(sexpr l){
     if( null(l) ) return 0;
     if( buono(car(l)) )
         return 1 + conta( cdr(l) );
     return conta( cdr(l) );
 }

 

4.  Scrivere una funzione che, avuto in ingresso una lista omogenea di stringhe, restituisce la lista delle lunghezze.

input: sexpr
output: sexpr

Se la lista in ingresso è vuota restituisce la lista vuota;
altrimenti restituisce l'atomo contenente la lunghezza della prima stringa concatenato a tutti gli altri atomi contenenti le lunghezze delle rimanenti stringhe.

sexpr lunghezze(sexpr l) {
     if( null(l) ) return make_nil();
     return cons(lungo(car(l)), lunghezze(cdr(l));
}

sexpr lungo (sexpr a){
     int *len = malloc(sizeof(int));
    
     *len = strlen((char*)dato(a));
     return make_elem(len, INT);
}

 

5.  Scrivere una funzione che, avuto in ingresso una lista omogenea di stringhe, restituisce  il numero di stringhe di lunghezza superiore ad n.

input: lista, n
output: intero

se la lista in ingresso è vuota restituisci 0 (non ci sono stringhe di lunghezza superiore ad n).
se la lunghezza della stringa contenuta nel primo elemento della lista è maggiore di n
     restituisci 1 + conta le stringhe rimanenti
altrimenti
     conta solo le stringhe rimanenti


int conta( sexpr l, int n){
     if( null(l) ) return 0;
     if(lunghezza(car(l)) > n)
         return 1 + conta(cdr(l));
     return conta(cdr(l));
}

int lunghezza(sexpr a) {
     return strlen((char*)dato(a));
}

 

6.  Scrivere una funzione che, avuto in ingresso una lista omogenea di interi positivi, calcola la somma dei primi n interi.

 

input: lista, n
output: intero

se la lista è vuota restituisco 0;
se n = 0 restituisco 0

restituisco il primo elemento sommato alla somma dei rimanti n-1;

int somma(sexpr l, int n) {
     if( null(l) ) return 0;
     if( n == 0 ) return 0;
     return *(int*)dato(car(l)) + somma(cdr(l), n-1);
}

Per ogni esercizio svolto produrre, quando possibile,  la descrizione del problema e la codifica in C.
Ogni esercizio verrà valutato (punti 1) solo se contiene la codifica.