<div align="center"><big><b>Programmazione I (canale P-Z) a.a. 2007-2008<br> </b></big> Docente: R. Silvestri Esercitatore: A. Carosi Tutor: J. Stefa<br> Esercizi di preparazione all'esame - 7 gennaio 2008 </div> <br> <div align="center"><big><b>Prima parte</b></big></div> <dl><b>Esercizio 1</b> <dd>Scrivere una funzione, con prototipo <tt>char *DelChar(const char *str, char d)</tt> che ritorna una stringa, allocata dinamicamente, ottenuta eliminando dalla stringa <tt>str</tt> tutte le eventuali occorrenze del carattere <tt>d</tt>. La stringa ritornata non deve usare più memoria di quella strettamente necessaria. Ad esempio <tt>DelChar("programma", 'a')</tt> ritorna la stringa <tt>"progrmm"</tt>. </dd> <b>Soluzione</b> <dd> <tt><pre> 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; } </pre></tt> </dd> </dl> <dl><b>Esercizio 2</b> <dd>Scrivere una funzione che preso in input un vettore di interi <tt>V</tt> e la sua dimensione <tt>n</tt>, riordina gli elementi di <tt>V</tt> in senso inverso. Il prototipo della funzione è <tt>void Inverti(int V[], int n)</tt>. Ad esempio se <tt>V = [2, -7, 5, 2, 76]</tt>, la funzione lo inverte così <tt>V = [76, 2, 5, -7, 2]</tt>. </dd> <b>Soluzione</b> <dd> <tt><pre> 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--; } } </pre></tt> </dd> </dl> <dl><b>Esercizio 3</b> <dd>Scrivere una funzione, con prototipo <tt>void</tt> <tt>PrintNumOcc(const char *str1, const char *str2)</tt>, che per ogni carattere distinto in <tt>str1</tt> stampa il numero di occorrenze di quel carattere in <tt>str2</tt>. Ad esempio, <tt>PrintNumOcc("pennino", "penna")</tt> deve stampare: <tt><pre> p 1 e 1 n 2 i 0 o 0 </pre></tt> </dd> <b>Soluzione</b> <dd> <tt><pre> /* 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. } </pre></tt> </dd> </dl> <hr width="100%" size="2"><br> <div align="center"><big><b>Seconda parte</b></big></div> <dl><b>Esercizio 4</b> <dd>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: <tt><pre> typedef struct SList { char str[30]; struct SList *next; } SList; </pre></tt> Il prototipo della funzione è <tt> void Ripulisci(SList *)</tt>. La memoria degli elementi eliminati deve essere rilasciata. </dd> <b>Soluzione</b> <dd> <tt><pre> 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); } } </pre></tt> </dd> </dl> <dl><b>Esercizio 5</b> <dd>Data una sequenza di numeri diciamo che un numero <i>x</i> della sequenza è un <i>massimo locale</i> se sia il numero che precede <i>x</i> che quello che lo segue sono strettamente minori di <i>x</i> (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: <tt><pre> typedef struct ENum { float n; struct ENum *next; } ENum; </pre></tt> Il prototipo della funzione è <tt>float *Massimi(const ENum *L, long *dim)</tt>. In <tt>*dim</tt> restituisce la dimensione del vettore ritornato (che deve essere allocato dinamicamente). Il vettore non deve essere sovradimensionato. Ad esempio se la lista è <tt>12 -> 3 -> 7 -> 4 -> 3 -> 2 -> 5 -> 1 -> 8 -> 8</tt> allora la funzione ritorna il vettore <tt>[7, 5]</tt> e in <tt>*dim</tt> restituisce <tt>2</tt>. </dd> <b>Soluzione</b> <dd> <tt><pre> /* 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; } </pre></tt> </dd> </dl> <dl><b>Esercizio 6</b> <dd>Scrivere una funzione, con prototipo <tt>long</tt> <tt>CatFiles(char *conF, char *catF)</tt>, che appende il contenuto del file il cui nome è nella stringa <tt>catF</tt> al file il cui nome è nella stringa <tt>conF</tt> 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 <tt>conF</tt> è <tt>Gli?esami?</tt> e il contenuto del file <tt>catF</tt> è <tt>non?finiscono?mai</tt> allora la funzione rende il contenuto del file <tt>conF</tt> uguale a <tt>Gli?esami?non?finiscono?mai</tt> e ritorna <tt>27</tt>. </dd> <b>Soluzione</b> <dd> <tt><pre> 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; } </pre></tt> </dd> </dl>
This topic: Programmazione1
>
WebHome
>
Prog1PZ
>
EsprepPZ0708
>
P070108PZ0708
Topic revision: r1 - 2008-01-07 - TizianaCalamoneri
Copyright © 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