Programmazione I    (canale P-Z) a.a. 2007-2008
Docente: R. Silvestri     Esercitatore: A. Carosi     Tutor: J. Stefa
Esercizi di preparazione all'esame - 14 gennaio 2008

Prima parte

Esercizio 1
Scrivere una funzione, con prototipo long *IndMax(const int V[], long n, long *nMax), che preso in input un vettore V di dimensione n, ritorna un vettore di long allocato dinamicamente contenente gli indici degli elementi di V che hanno valore uguale al massimo intero presente in V e in *nMax restituisce il numero di tali elementi. Il vettore ritornato non deve usare più memoria di quella strettamente necessaria. Se V = [-1, 2, 7, -5, 7] allora la funzione ritorna il vettore [2, 4] e in *nMax restituisce 2.
Soluzione
long *IndMax(const int  V[], long n, long  *nMax)
{
    long *ind = NULL;            //Inizializza i valori di ind e *nMax cosicche'
    *nMax = 0;                   //se n <= 0 ritorna NULL e in *nMax restituisce 0.
    if (n > 0) {                 
        long i, k;
        int max = V[0]; 
        for (i = 1 ; i < n ; i++)             //Calcola il valore massimo di V
            if (V[i] > max) max = V[i];
        for (i = 0 ; i < n ; i++)             //Calcola il numero di elementi di V
            if (V[i] == max) (*nMax)++;       //con valore massimo.
        ind = malloc((*nMax)*sizeof(long));   //Alloca il nuovo vettore
        for (k = 0, i = 0 ; i < n ; i++)      //Scrivi nel nuovo vettore gli indici
            if (V[i] == max) ind[k++] = i;    //degli elementi con valore massimo.
    }
    return ind;
}
Esercizio 2
Scrivere una funzione che presi in input tre interi non negativi nA, nB, nC, restituisce una stringa allocata dinamicamente che consiste di nA caratteri 'A' seguiti da nB caratteri 'B' seguiti da nC caratteri 'C'. Il prototipo della funzione è char *ABCStringa(int nA, int nB, int nC). Ad esempio se nA = 2, nB = 1 e nC = 4 la funzione deve restituire la stringa "AABCCCC".
Soluzione
char *ABCStringa(int nA, int nB, int nC)
{
    char *stringa = malloc((nA + nB + nC + 1)*sizeof(char));   //Alloca la stringa
    int n, i = 0;                //La variabile i conterra' sempre l'indice del
                                 //prossimo carattere (non ancora scritto).
    for (n = nA ; n > 0 ; n--) stringa[i++] = 'A';       //Scrivi le A
    for (n = nB ; n > 0 ; n--) stringa[i++] = 'B';       //Scrivi le B
    for (n = nC ; n > 0 ; n--) stringa[i++] = 'C';       //Scrivi le C
    stringa[i] = '\0';
    return stringa;
}

Esercizio 3
Scrivere una funzione che preso in input un vettore di interi ordinato in senso non decrescente e la sua dimensione, elimina dal vettore tutti i duplicati compattandolo e ritorna il numero di elementi eliminati (la dimensione del vettore comunque non cambia). Il prototipo della funzione è long EliminaDuplicati(int V[], long dim). Ad esempio se V = [2, 4, 4, 5, 7, 7, 7] la funzione modifica il vettore in modo tale che i primi 4 elementi del vettore siano [2, 4, 5, 7] e ritorna 3.
Soluzione
long EliminaDuplicati(int V[], long dim)
{
    long k = 0, i;
    for (i = 1 ; i < dim ; i++) {
        if (V[i] != V[k]) {
            k++;
            V[k] = V[i];
        }
    }
    return dim - (k + 1);
} 


Seconda parte
Esercizio 4
Scrivere una funzione che preso in input una lista di interi, per ogni elemento della lista modifica l'intero in esso contenuto in modo tale che contenga la somma di tutti gli interi contenuti nella lista a partire da quel elemento. Il tipo degli elementi della lista è:
typedef struct Elem {
    int          intero;
    struct Elem *next;
} Elem, *List;
Il prototipo della funzione è void SomList(List). Ad esempio se la lista è 2 -> 5 -> 3 -> 13 allora la funzione modifica la lista così 23 -> 21 -> 16 -> 13.
Soluzione
/* Funzione ausiliaria che ritorna la somma degli interi della lista a partire
   dall'elemento e.                                                           */
int Somma(const Elem *e)
{
    int s = 0;
    while (e != NULL) {
        s += e->intero;
        e = e->next;
    }
    return s;
}

void SomList(List L)
{
    while (L != NULL) {
        L->intero = Somma(L);
        L = L->next;
    }
} 
Esercizio 5
Si consideri il seguente tipo:
typedef struct VStr {
    long         val;
    char *       str;        //stringa allocata dinamicamente
    struct VStr *next;
} VStr, *LStr;
Scrivere una funzione, con prototipo int Comp(LStr L), che presa in input la lista L, ordinata in senso non decrescente rispetto al campo val, la modifica in modo tale che elementi consecutivi che hanno lo stesso valore del campo val sono sostituiti da un elemento il cui valore del campo val è lo stesso e il campo str è la stringa prodotta dalla concatenazione, nell'ordine, delle stringhe degli elementi sostituiti. La funzione ritorna il numero massimo di elementi con lo stesso valore del campo val. Inoltre la funzione non deve modificare il puntatore al primo elemento. La memoria non più usata deve essere rilasciata e i nuovi blocchi di memoria non devono essere più grandi del necessario. Ad esempio se la lista è {5, "AA"} -> {5, "BBB"} -> {7, "C"} -> {8, "D"} -> {8, "GG"} -> {8, "F"} allora la funzione la modifica così {5, "AABBB"} -> {7, "C"} -> {8, "DGGF"} e ritorna 3.
Soluzione
int  Comp(LStr L)
{
    int max = 0, count = 0;
    LStr prev = NULL;                    //Manterra' il puntatore al primo elemento
    long val;                            //di una sequenza di elementi da sostituire.  
    while (L != NULL) {
        if (prev != NULL && val == L->val) {     //Se e' un elemento  di una sequenza
            int newLen = strlen(prev->str) + strlen(L->str);   //di elementi da sost.
            prev->str = realloc(prev->str, (newLen + 1)*sizeof(char));
            strcat(prev->str, L->str);           //Rialloca un blocco sufficiente per
            prev->next = L->next;                //mantenere la concatenazione.
            free(L->str);                        //Sgancia l'elemento dalla lista e
            free(L);                             //rilascia la memoria della stringa
            L = prev->next;                      //e dell'elemento.
            count++;
        } else {
            if (count > max) max = count;
            count = 1;
            val = L->val;
            prev = L;
            L = L->next;
        }
    }
    if (count > max) max = count;
    return max;
}
Esercizio 6
Scrivere una funzione, con prototipo void InvFile(char *nameF, char *newF), che legge il file di tipo testo il cui nome è nella stringa nameF, contenente una sequenza di numeri interi separati da spazi, e crea un nuovo file di testo, con nome dato dalla stringa newF, e vi scrive la sequenza inversa. Ad esempio, se il file nameF contiene la sequenza 3 7 -2 15 allora il nuovo file creato dalla funzione deve contenere 15 -2 7 3.
Soluzione
void  InvFile(char *nameF, char  *newF)
{
    FILE *f = fopen(nameF, "r");                //Apri il file in lettura
    int n, lenF = 0;
    while (fscanf(f, "%d", &n) == 1) lenF++;    //Conta gli interi nel file
    int k = 0, v[lenF];  //Vettore a dimensione variabile atto a contenere gli interi del file
    rewind(f);           //Riporta il cursore del file all'inizio
    while (fscanf(f, "%d", &(v[k])) == 1) k++;  //Copia gli interi del file nel vettore v
    fclose(f);
    FILE *nF = fopen(newF, "w");                //Crea ed apri il nuovo file
    for (k = lenF - 1 ; k >= 0 ; k--)           //Scrivi nel nuovo file gli interi in
        fprintf(nF, "%d ", v[k]);               //ordine inverso.
    fclose(nF);
}


This topic: Programmazione1 > WebHome > Prog1PZ > EsprepPZ0708 > P140108PZ0708
Topic revision: r1 - 2008-01-14 - TizianaCalamoneri
 
This site is powered by the TWiki collaboration platform Powered by PerlCopyright © 2008-2024 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback