Visualizzazione dei risultati da 1 a 2 su 2
  1. #1

    difficoltà a scrivere il main delle funzioni passati in C

    Ho bisogno di grande aiuto,il docente universitario ha messo le soluzioni di alcuni esercizi di preparazioni d'esame solo con le funzioni richieste nel testo, però per curiosità volevo vedere come andrebbero implementate con codice completo con il main.

    Esercizio 1
    Scrivere una funzione void clean(SList L) che preso in input il puntatore L al primo elemento di una lista ordinata di stringhe, elimina i duplicati. La funzione non deve modificare il primo elemento della lista. Gli elementi della lista hanno il seguente tipo:

    typedef struct SElem {
    char str[30];
    struct SElem *next;
    } SElem, *SList;

    La memoria degli elementi eliminati deve essere rilasciata. Ad esempio, se la lista è "BLUE" -> "BLUE" -> "GREEN" -> "RED" -> "RED" -> "YELLOW" allora la funzione la modifica così: "BLUE" -> "GREEN" -> "RED" -> "YELLOW".

    codice:
    #include <string.h>
    #include <stdlib.h>
    
    typedef struct SElem {
        char          str[30];
        struct SElem *next;
    } SElem, *SList;
    
    void clean(SList L) {
        if (L == NULL || L->next == NULL)
            return;
        SElem *e = L;
        do {
            if (strcmp(e->str, e->next->str) == 0) { //Se le stringhe sono uguali,
                SElem *p = e->next;                  //elimina il prossimo elemento.
                e->next = p->next;
                free(p);
            } else e = e->next;
        } while (e->next != NULL);
    }
    
    int main(){
    // dovrei leggere l'array di stringhe e passarlo alla funzione.
    Esercizio 2
    Scrivere una funzione 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.

    codice:
    #include <stdio.h>
    
    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);
    }
    int main(){
    
         // cosa dovrei leggere se ho gia letto tutto nella funzione?
    Esercizio 3
    Scrivere una funzione int **table(int n, int (*f)(int, int)) che ritorna una matrice quadrata di dimensione n di interi, allocata dinamicamente, riempita con i valori dati dalla funzione f (l'elemento (i, j) della matrice ha valore dato da f(i, j), per 0 <= i, j < n). Gli elementi della matrice ritornata si devono poter accedere tramite la sintassi delle parentesi quadre. Ad esempio, se n = 5 e la funzione f è la funzione che ritorna il prodotto dei due interi in input, allora la chiamata table(5, f) ritorna la seguente matrice:

    0 0 0 0 0
    0 1 2 3 4
    0 2 4 6 8
    0 3 6 9 12
    0 4 8 12 16

    codice:
    #include <stdlib.h>
    
    int **table(int n, int (*f)(int, int)) {
        int **M = malloc(n*sizeof(int *));    //Alloca il vettore dei puntatori alle
        int i, j;                                //righe della matrice.
        for (i = 0 ; i < n ; i++)             //Alloca le righe della matrice
            M[i] = malloc(n*sizeof(int));
        for (i = 0 ; i < n ; i++) {
            for (j = 0 ; j < n ; j++)
                M[i][j] = f(i, j);
        }
        return M;
    }
    int main(){
    
    // ok qua devo leggere la matrice e passarlo alla funzione
    Esercizio 4
    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 Num {
    float n;
    struct Num *next;
    } Num, *NList;

    Il prototipo della funzione è float *localMax(NList L, int *pcount). In *pcount restituisce la dimensione del vettore ritornato (che deve essere allocato dinamicamente). Il vettore non deve essere sovradimensionato. Ad esempio, se la lista è 12 -> 3.5 -> 7.1 -> 4 -> 3 -> 2 -> 5.2 -> 1 -> 8 -> 8 allora la funzione ritorna il vettore [7.1, 5.2] e in *pcount restituisce 2.

    codice:
    #include <stdlib.h>
    
    typedef struct Num {
        float       n;
        struct Num *next;
    } Num, *NList;
    
    /* Funzione ausiliaria che ritorna il puntatore al primo massimo locale della
     * lista a partire dall'elemento p. Se non ci sono massimi ritorna NULL. */
    Num *firstMax(Num *p) {
        if (p == NULL || p->next == NULL) return NULL;
        else {
            float prec = p->n;
            p = p->next;
            while (p->next != NULL && !(p->n > prec && p->n > p->next->n)) {
                prec = p->n;
                p = p->next;
            }
            return (p->next != NULL ? p : NULL);
        }
    }
    
    float *localMax(NList L, int *pcount) {
        float *maxArray = NULL;
        int maxCount = 0;
        Num *e = L;
        while ((e = firstMax(e)) != NULL) {
            maxArray = realloc(maxArray, (maxCount + 1)*sizeof(float));
            maxArray[maxCount++] = e->n;
        }
        *pcount = maxCount;
        return maxArray;
    }
    
    int main(){
    
    // non saprei cosa scrivere in questo caso
    
    return 0;
    Esercizio 5
    Si consideri il seguente tipo:

    typedef struct {
    long task;
    int h; //ore: 0 - 23
    int m; //minuti: 0 - 59
    int s; //secondi: 0 - 59
    } TaskRec;

    Scrivere una funzione int updateTasks(char *taskF, int hh, int mm, int ss) che preso in input il nome taskF di un file binario che contiene una sequenza di record di tipo TaskRec elimina da esso tutti i record il cui orario (dato dai campi h, m ed s) è antecedente all'orario dato da hh, mm ed ss (assumendo che tutti gli orari si riferiscano allo stesso giorno). La funzione ritorna il numero di record nel file aggiornato. Eliminare un record significa che gli eventuali record che vengono dopo nel file devono essere "spostati" per chiudere il "buco" lasciato dal record eliminato. Ad esempio, se inizialmente il file taskF contiene la sequenza di record: {1234, 2, 15, 23}, {2345, 7, 30, 15}, {1238, 7, 30, 11}, {2351, 13, 24, 53} allora la chiamata updateTask(taskF, 7, 30, 15) ritorna 2 e la sequenza contenuta nel file diventa: {2345, 7, 30, 15}, {2351, 13, 24, 53}.

    codice:
    #include <stdio.h>
    
    typedef struct {
        long task;
        int  h;     //ore: 0 - 23
        int  m;     //minuti: 0 - 59
        int  s;     //secondi: 0 - 59
    } TaskRec;
    
    /* Funzione ausiliaria che ritorna 1 se l'orario (h, m, s) e' antecedente
       all'orario (hh, mm, ss), altrimenti ritorna 0. */
    int ant(int h, int m, int s, int hh, int mm, int ss) {
        if (h < hh) return 1;
        if (h == hh && m < mm) return 1;
        if (h == hh && m == mm && s < ss) return 1;
        return 0;
    }
    
    int updateTasks(char *taskF, int hh, int mm, int ss) {
        FILE *f = fopen(taskF, "r+b");  //Apri il file binario in lettura e scrittura
        int nc = 0, posLast = 0, posNext = 0; //posLast manterra' la posizione in cui spostare
        TaskRec rec;                          //il prossimo record valido e posNext manterra' la
        while (fread(&rec, sizeof(rec), 1, f) == 1) {  //posizione del prossimo record da leggere.
            if (!ant(rec.h, rec.m, rec.s, hh, mm, ss)) { //Se non e' antecedente...
                fseek(f, posLast, SEEK_SET);             //spostalo (o riscrivilo)
                fwrite(&rec, sizeof(rec), 1, f);
                posLast += sizeof(rec);
                nc++;
            }
            posNext += sizeof (rec);
            fseek(f, posNext, SEEK_SET);
        }
        fclose(f);
        return nc;
    }
    
    int main()
    
    // durante la lezione abbiamo visto il main con argomenti
    Esercizio 6
    Si consideri il seguente tipo:

    typedef struct Elem {
    char * str; // stringa allocata dinamicamente
    struct Elem *next;
    } Elem, *List;

    Scrivere una funzione List minstr(List L, int (*cmp)(const char *, const char *)) che elimina dalla lista di stringhe L la stringa che risulta essere minima rispetto alla relazione d'ordine data dalla funzione cmp(). La funzione cmp(s1, s2) ritorna -1 se s1 < s2, 0 se s1 = s2 e 1 se s1 > s2. La funzione minstr() deve ritornare il puntatore alla lista modificata. Ad esempio, se la lista L è "verde" -> "giallo" -> "rosso" -> "blu" -> "rosso" allora la chiamata minstr(L, strcmp) modifica la lista così: "verde" -> "giallo" -> "rosso" -> "rosso".

    codice:
    #include <stdlib.h>
    
    typedef struct Elem {
        char *       str;    // stringa allocata dinamicamente
        struct Elem *next;
    } Elem, *List;
    
    List minstr(List L, int (*cmp)(const char *, const char *)) {
        if (L == NULL) return NULL;
        Elem *min = L, *curr = L->next;
        while (curr != NULL) {                //Scorri la lista per trovare l'elemento
            if (cmp(curr->str, min->str) < 0) //con la stringa minima.
                min = curr;
            curr = curr->next;
        }
        Elem *prev = NULL;
        curr = L;
        while (curr != min) {          //Scorri la lista mantenendo il puntatore
            prev = curr;               //all'elemento precedente (prev).
            curr = curr->next;
        }
        if (prev == NULL) L = L->next;    //Sgancia l'elemento minimo dalla lista
        else prev->next = min->next;
        free(min->str);                   //Libera la memoria dell'elemento eliminato
        free(min);
        return L;
    }
    int main(){
    
    //se non sbaglio in questo caso devo solo leggere la lista e passarlo alla funzione.
    Esercizio 7
    Scrivere una funzione che presa in input una lista di stringhe crea una stringa uguale alla concatenazione delle stringhe della lista. Il tipo degli elementi della lista è il seguente:

    typedef struct SElem {
    char * str;
    struct SElem *next;
    } SElem;

    Il prototipo della funzione è char *listToStr(SElem *). Ovviamente la stringa ritornata deve essere allocata dinamicamente. Ad esempio, se la lista è "List" -> "a di es" -> "" -> "e" -> "mpio" allora la funzione deve restituire la stringa "Lista di esempio".

    codice:
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct SElem {
        char *        str;
        struct SElem *next;
    } SElem;
    
    char *listToStr(SElem *L) {
        char *str;
        const SElem *p = L;
        long len = 0;               //Calcola la lunghezza della stringa che
        while (p != NULL) {         //e' uguale alla somma delle lunghezze
            len += strlen(p->str);  //delle stringhe della lista.
            p = p->next;
        }
        str = malloc(len + 1);      //Alloca la stringa e
        str[0] = '\0';              //inizializzala a vuota.
        p = L;
        while (p != NULL) {            //Concatena le stringhe della lista
            strcat(str, p->str);       //copiandole nella stringa.
            p = p->next;
        }
        return str;
    }
    int mian(){
    
    //leggo le stringhe e passo alla funzione?

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,464
    Non ho capito la richiesta ... vorresti scritto completamente il main?

    Ma perchè non ne proponi uno tu ?
    No MP tecnici (non rispondo nemmeno!), usa il forum.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.