Corsi di laurea in Ingegnera Elettronica e Ingegneria Gestionale Fondamenti di Programmazione / Fondamenti di Informatica I
Prova scritta del 1
oluglio 2014 Esercizio 1 (17 punti)
Un file di testo è utilizzato per rappresentare un insieme di sequenze di numeri interi.
Ogni numero è scritto su una riga del file e può essere immediatamente seguito dal carattere ';' (e in tal caso il numero appartiene a tutte le sequenze) oppure dal carattere '|', da un secondo numero e infine dal ';'. In questo caso il secondo numero rappresenta un’alternativa al primo e quidi appartiene a una sequenza diversa.
Le sequenze rappresentate dal file sono tutte quelle che contengono un numero preso da ciascuna riga in tutte le possibili combinazioni.
Si veda l’esempio a lato.
Si scriva una funzione in linguaggio C che riceva come argomenti il nome di un file siffatto e una matrice quadrata di interi. La dimensione della matrice sia definita da una costante N. La funzione deve riempire le righe della matrice secondo lo schema sopra riportato e restituire, in un’apposita struttura, il numero di righe riempite e la loro lunghezza (cioè la lunghezza delle sequenze generate, che è la stessa per tutte).
Si assuma che la matrice sia sufficientemente grande per contenere tutte le sequenze generate tramite il file di ingresso. Si assuma inoltre che il file contenga almeno un numero e quindi esista almeno una sequenza.
Si osservi che ogni volta che si incontra una coppia di valori alternativi è necessario risolvere questi due sottoproblemi:
- raddoppiare le righe della matrice riempite finora;
- aggiungere alle righe originali il primo valore della coppia e a quelle ricopiate il secondo valore.
#include <stdio.h>
#include <stdlib.h>
#define N 100
struct dimensioni {
int numero_sequenze;
int lunghezza_sequenze;
};
struct dimensioni genera_sequenze (char nomefile[], int m[N][N]);
void raddoppia_righe (int m[N][N], int r, int c);
void aggiungi_valore (int v, int m[N][N], int prima_riga, int ultima_riga, int ncolonne);
void stampa_matrice (int m[N][N], int r, int c);
int main (int argc, char *argv[]) {
int m[N][N];
struct dimensioni dim;
if (argc != 2) {
printf ("serve il nome del file\n");
exit (EXIT_FAILURE);
}
dim = genera_sequenze (argv[1], m);
stampa_matrice (m, dim.numero_sequenze, dim.lunghezza_sequenze);
return EXIT_SUCCESS;
}
Per esempio, il file
12;
34|37;
1|255;
4;
5|9;
rappresenta le sequenze:
12 34 1 4 5
12 37 1 4 5
12 34 255 4 5
12 37 255 4 5
12 34 1 4 9
12 37 1 4 9
12 34 255 4 9
12 37 255 4 9
struct dimensioni genera_sequenze (char nomefile[], int m[N][N]) {
FILE *fpin;
int nsequenze, lsequenze;
int valore, valore_alt;
char separatore;
struct dimensioni dim;
nsequenze = 1; /* esiste almeno una sequenza, al limite di lunghezza nulla */
lsequenze = 0;
if ((fpin = fopen (nomefile, "r")) == NULL) {
printf ("errore apertura file di ingresso\n");
exit (EXIT_FAILURE);
}
while (fscanf (fpin, "%d%c", &valore, &separatore) != EOF) {
if (separatore == ';') {
aggiungi_valore (valore, m, 0, nsequenze-1, lsequenze);
lsequenze++;
}
else /* separatore era '|' */
{
fscanf (fpin, "%d%c", &valore_alt, &separatore);
raddoppia_righe (m, nsequenze, lsequenze);
aggiungi_valore (valore, m, 0, nsequenze-1, lsequenze);
aggiungi_valore (valore_alt, m, nsequenze, 2*nsequenze, lsequenze);
lsequenze++;
nsequenze = nsequenze * 2;
} }
fclose (fpin);
dim.numero_sequenze = nsequenze;
dim.lunghezza_sequenze = lsequenze;
return dim;
}
void raddoppia_righe (int m[N][N], int r, int c) {
int i, j;
for (i = 0; i < r; i++) for (j = 0; j < c; j++) m[r+i][j] = m[i][j];
return;
}
void aggiungi_valore (int v, int m[N][N], int prima_riga, int ultima_riga, int ncolonne) {
int i, j;
for (i = prima_riga; i <= ultima_riga; i++) m[i][ncolonne] = v;
return;
}
void stampa_matrice (int m[N][N], int r, int c) {
int i, j;
for (i = 0; i < r; i++) {
for (j = 0; j < c; j++) printf ("%5d", m[i][j]);
printf ("\n");
} return;
}
Esercizio 2 (13 punti)
Un file contiene le informazioni su un insieme di calciatori (uno per riga). Ciascuna riga contiene il nome completo (inteso come cognome e nome), il ruolo, il numero di gol segnati e il numero di presenze. Le informazioni sono separate tra loro da una virgola e uno spazio. Il nome può ovviamente contenere spazi, mentre il ruolo non ha spazi.
Come esempio, si consideri il seguente file.
Bianchi Mauro, attaccante, 10, 20 Rossi Paolo, difensore, 3, 25
Verdi Giuseppe, centrocampista, 7, 20 De Rossi Giovanni, centrocampista, 5, 18 Neri Pier Paolo, difensore, 6, 14
Bianchi Alessandro, attaccante, 9, 19 Viola Pier Giorgio, difensore, 6, 10
Si scriva una funzione C che riceva come parametri il nome di un file siffatto ed una stringa contenente un ruolo. La funzione deve restituire, tramite un ulteriore parametro, il nome completo del giocatore di quel ruolo che ha segnato più gol di tutti. A parità di gol segnati, si deve restituire l'ultimo in ordine di presenza nel file.
Nel file dell'esempio, se il ruolo è "centrocampista" la funzione deve restituire "Verdi Giuseppe", mentre se il ruolo è "difensore" deve restituire "Viola Pier Giorgio".
Nel caso in cui non siano presenti giocatori con il ruolo richiesto, la funzione dovrà restituire la stringa convenzionale "Nessun giocatore".
#include <stdio.h>
#include <stdlib.h>
struct calciatore {
char nome[64];
char ruolo[32];
int gol;
int presenze;
};
struct calciatore estrai_dati (char s[]);
void goleador (char nomefile[], char ruolo[], char nome_goleador[]);
int main (int argc, char *argv[]) {
char nome_goleador[64];
if (argc != 3) {
printf ("uso: calciatori <nomefile> <ruolo>\n");
exit (EXIT_FAILURE);
}
goleador (argv[1], argv[2], nome_goleador);
printf ("%s\n", nome_goleador);
return EXIT_SUCCESS;
}
struct calciatore estrai_dati (char s[]) {
struct calciatore c;
int i, j;
char t[32];
i = 0;
j = 0;
while (s[i] != '\0' && s[i] != ',') c.nome[j++] = s[i++];
c.nome[j] = '\0';
i++;
while (s[i] != '\0' && s[i] != ' ') i++;
i++;
j = 0;
while (s[i] != '\0' && s[i] != ',') c.ruolo[j++] = s[i++];
c.ruolo[j] = '\0';
while (s[i] != '\0' && s[i] != ' ') i++;
i++;
j = 0;
while (s[i] != '\0' && s[i] != ',') t[j++] = s[i++];
t[j] = '\0';
c.gol = atoi(t);
while (s[i] != '\0' && s[i] != ' ') i++;
i++;
j = 0;
while (s[i] != '\0' && s[i] != ',') t[j++] = s[i++];
t[j] = '\0';
c.presenze = atoi(t);
return c;
}
void goleador (char nomefile[], char ruolo[], char nome_goleador[]) {
FILE *fp;
char s[128];
struct calciatore c, cmigliore;
int inizializzato = 0;
if ((fp = fopen (nomefile, "r")) == NULL) {
printf ("errore di apertura del file di input\n");
exit (EXIT_FAILURE);
}
while (fgets (s, 128, fp) != NULL) {
c = estrai_dati (s);
if (!strcmp(c.ruolo, ruolo)) {
if (!inizializzato) {
cmigliore = c;
inizializzato = 1;
} else {
if (c.gol >= cmigliore.gol) cmigliore = c;
} } }
if (!inizializzato)
strcpy (nome_goleador, "Nessun giocatore");
else
strcpy (nome_goleador, cmigliore.nome);
return;
}