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