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