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

Prima parte

Esercizio 1
Scrivere una funzione, con prototipo char *DelChar(const char *str, char d) che ritorna una stringa, allocata dinamicamente, ottenuta eliminando dalla stringa str tutte le eventuali occorrenze del carattere d. La stringa ritornata non deve usare più memoria di quella strettamente necessaria. Ad esempio DelChar("programma", 'a') ritorna la stringa "progrmm".
Soluzione
char *DelChar(const char  *str, char d)
{
    long i, j, ndc;
    for (ndc = 0, i = 0 ; str[i] != '\0' ; i++)       //Calcola il numero di caratteri
        if (str[i] == del) ndc++;                     //da eliminare.
            //Alloca lo spazio di memoria strettamente necessario per la nuova stringa
    char *newStr = malloc((strlen(str) - ndc + 1)*sizeof(char));
    for (j = 0, i = 0 ; string[i] != '\0' ; i++)      //Copia i caratteri diversi da d
        if (str[i] != d) newStr[j++] = str[i];        //nella nuova stringa.
    newStr[j] = '\0';
    return newStr;
}
Esercizio 2
Scrivere una funzione che preso in input un vettore di interi V e la sua dimensione n, riordina gli elementi di V in senso inverso. Il prototipo della funzione è void Inverti(int V[], int n). Ad esempio se V = [2, -7, 5, 2, 76], la funzione lo inverte così V = [76, 2, 5, -7, 2].
Soluzione
void Inverti(int V[], int n)
{
    int i = 0, j = n - 1;    //L'indice i procede dall'inizio verso la fine del
    while (i < j) {          //vettore e l'indice j dalla fine verso l'inizio.
        int c = V[i];        //Scambia V[i] e V[j]
        V[i] = V[j];
        V[j] = c;
        i++;
        j--;
    }
}

Esercizio 3
Scrivere una funzione, con prototipo void PrintNumOcc(const char *str1, const char *str2), che per ogni carattere distinto in str1 stampa il numero di occorrenze di quel carattere in str2. Ad esempio, PrintNumOcc("pennino", "penna") deve stampare:
     p 1
     e 1
     n 2
     i 0
     o 0
Soluzione
/* Funzione ausiliaria che ritorna il numero di occorrenze del carattere c
   nei primi n caratteri di s.                                             */
long CountOcc(const char *s, long n, char c)
{
    long k, nOcc = 0;
    for (k = 0 ; k < n ; k++) if (s[k] == c) nOcc++;
    return nOcc;
}

void PrintNumOcc(const char *str1, const char *str2)
{
    long k, len2 = strlen(str2);
    for (k = 0 ; str1[k] != '\0' ; k++) {    //Per ogni carattere c di str1...
        char c = str1[k];
        if (CountOcc(str1, k, c) == 0)       //Se e' la prima occorrenza di c in str1,       
            printf("%c %ld\n", c, CountOcc(str2, len2, c));   //stampa il numero di volte
    }                                                         //che c occorre in str2.
}


Seconda parte
Esercizio 4
Scrivere una funzione che preso in input il puntatore al primo elemento di una lista di stringhe ordinata, elimina i duplicati. La funzione non deve modificare il primo elemento della lista. Gli elementi della lista hanno il seguente tipo:
typedef struct SList {
    char          str[30];
    struct SList *next;
} SList;
Il prototipo della funzione è void Ripulisci(SList *). La memoria degli elementi eliminati deve essere rilasciata.
Soluzione
void Ripulisci(SList *L)
{
    if (L != NULL && L->next != NULL) {
        SList *e = L;
        do {
            if (strcmp(e->str, e->next->str) == 0) {   //Se le stringhe sono uguali
                SList *p = e->next;                    //elimina il prossimo elemento.
                e->next = p->next;
                free(p);
            } else e = e->next;
        } while (e->next != NULL);
    }
}
Esercizio 5
Data una sequenza di numeri diciamo che un numero x della sequenza è un massimo locale se sia il numero che precede x che quello che lo segue sono strettamente minori di x (né il primo né l'ultimo numero della sequenza può essere un massimo locale). Scrivere una funzione che presa in input una lista di numeri restituisce un vettore contenente i massimi locali della lista (nell'ordine in cui appaiono nella lista). Il tipo degli elementi della lista è il seguente:
typedef struct ENum {
    float        n;
    struct ENum *next;
} ENum;
Il prototipo della funzione è float *Massimi(const ENum *L, long *dim). In *dim restituisce la dimensione del vettore ritornato (che deve essere allocato dinamicamente). Il vettore non deve essere sovradimensionato. Ad esempio se la lista è 12 -> 3 -> 7 -> 4 -> 3 -> 2 -> 5 -> 1 -> 8 -> 8 allora la funzione ritorna il vettore [7, 5] e in *dim restituisce 2.

Soluzione
/* Funzione ausiliaria che ritorna il puntatore al primo massimo della lista L.
   Se non ci sono massimi ritorna NULL.                                        */
ENum *PrimoMax(const ENum *L)
{
    if (L == NULL || L->next == NULL) return NULL;
    else {
        float prec = L->n;
        L = L->next;
        while (L->next != NULL && (L->n <= prec || L->n <= L->next->n)) {
            prec = L->n;
            L = L->next;
        }
        return (L->next != NULL ? L : NULL);
    }
}

float *Massimi(const ENum *L, long *dim)
{
    float *vetMax = NULL;
    long nMax = 0;
    const ENum *e = L;
    while ((e = PrimoMax(e)) != NULL) nMax++;   //Conta i massimi
    if (nMax > 0) {
        long i = 0;
        vetMax = malloc(nMax*sizeof(float));   //Alloca il vettore dei massimi
        while ((L = PrimoMax(L)) != NULL) vetMax[i++] = L->n;
    }
    *dim = nMax;
    return vetMax;
}
Esercizio 6
Scrivere una funzione, con prototipo long CatFiles(char *conF, char *catF), che appende il contenuto del file il cui nome è nella stringa catF al file il cui nome è nella stringa conF e ritorna il numero di caratteri del primo file dopo l'aggiunta. Entrambi i files si assumono di tipo testo. Ad esempio, se il contenuto del file conF è Gli?esami? e il contenuto del file catF è non?finiscono?mai allora la funzione rende il contenuto del file conF uguale a Gli?esami?non?finiscono?mai e ritorna 27.
Soluzione
long CatFiles(char *conF, char *catF)
{
    FILE *fcon = fopen(conF, "r+");      //Apri il file conF in lettura e scrittura
    FILE *fcat = fopen(catF, "r");       //Apri il file catF in lettura
    long nc = 0;
    int c;
    while (fgetc(fcon) != EOF) nc++;     //Calcola il numero di caratteri di conF
    while ((c = fgetc(fcat)) != EOF) {   //Aggiungi il contenuto di catF a conF
        fputc(c, fcon);
        nc++;
    }
    fclose(fcon);
    fclose(fcat);
    return nc;
}


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