Problem solving avanzato Formulazione del problema Struttura dati e algoritmo Il programma 2 26 Politecnico di Torino 1
Dati in input (1/4) Sono dati due file di testo, contenenti le informazioni sulle operazioni di una ditta di import/export, che ha relazioni commerciali con società appartenenti a vari stati Un primo file (detto nel seguito F) contiene l elenco degli stati e delle società con cui esistono relazioni commerciali Un secondo file (detto nel seguito F1) contiene le informazioni su un certo numero di transazioni commerciali (con una delle società elencate in F) 4 26 Politecnico di Torino 2
Dati in input (2/4) Il file F contiene l elenco degli stati e delle società Nella prima riga due interi <nst> <nsoc> (separati da spazio): numero totale di stati e di società Nelle <nst> righe successive sono elencati gli stati, uno per riga, secondo il formato: <codice_stato> <nome_stato> <codice_stato> è un codice intero compreso tra e 99 (ogni stato ha un codice unico, non si garantisce che gli stati siano elencati per ordine crescente di codice) <nome_stato> è il nome dello stato, privo di spazi 5 Dati in input (3/4) Nelle <nsoc> righe finali del file sono elencate le società. Per ognuna, su una riga, viene riportato: <codice_stato> <nome_società> <codice_stato> è il codice dello stato cui appartiene la società <nome_società> è il nome della società 6 26 Politecnico di Torino 3
Dati in input (4/4) F1 contiene le informazioni su un insieme di transazioni commerciali, ognuna delle quali viene rappresentata, su una riga del file, secondo il formato: <nome_società> <importo> <data> <nome_società> è il nome della società <importo> (intero con segno) rappresenta l importo della transazione (negativo per importazione, positivo per esportazione) <data> è la data della transazione (formato gg/mm/aaaa) 7 Elaborazioni richieste (1/2) Leggere F e F1, i cui nomi sono ricevuti come argomenti sulla linea di comando Calcolare, e stampare su video Il numero totale delle transazioni (NT) e i bilanci complessivi delle transazioni di importazione e esportazione SI: somma degli importi relativi a importazioni SE: somma degli importi relativi a esportazioni 8 26 Politecnico di Torino 4
Elaborazioni richieste (2/2) Per ogni stato, il bilancio complessivo commerciale di import-export (sommatoria degli importi relativi a tutte le società appartenenti allo stato) Lo stato per cui è massimo il bilancio di importazione e quello per cui è massimo il bilancio di esportazione 9 Esempio F 5 1 4 Germania 3 Francia Stati_Uniti 2 Giappone 1 Corea 1 Kia 4 BMW 4 Mercedes 3 Peugeot 3 Citroen 2 Honda 2 Mitsubishi Chrisler General_Motors Chevrolet F1 Mitsubishi 11 21/1/24 Chrisler -3 1/2/24 General_Motors -2 1/2/24 Citroen -7 24/11/24 Chrisler -367 12/12/24... General Motors -14 14/12/24 Chevrolet -6 16/12/24 1 26 Politecnico di Torino 5
Struttura dati (1/2) Due tabelle, che contengono i dati letti dai file Tabella degli stati: contiene l elenco degli stati, identificati da codice e nome. Siccome i codici sono compresi tra e 99, è opportuno utilizzare il codice come indice in un vettore, per consentire la conversione da codice a nome con accesso diretto Tabella delle società: contiene l elenco delle società, per ognuna delle quali viene riportato il nome e il codice dello stato di appartenenza. La tabella permette di ricavare il codice dello stato a partire dal nome di una società 12 26 Politecnico di Torino 6
Struttura dati (2/2) Variabili (scalari) per le statistiche richieste Sommatoria delle importazioni Sommatoria delle esportazioni Un vettore per il bilancio di import-export dei singoli stati. Tale bilancio può essere aggiunto (come ulteriore campo) alla tabella degli stati NON è necessaria una struttura dati per l elenco delle transazioni, che possono essere lette e manipolate una alla volta 13 Rappresentazione della struttura dati Tabella degli stati Tabella delle società 1 2 3 4 Stati Uniti Corea Giappone... Francia Germania 1 41 42 3 4 5 6 7 8 Kia BMW Mercedes...... Chevrolet 14 26 Politecnico di Torino 7
Rappresentazione della struttura dati Tabella degli stati Tabella delle società 1 2 3 4 Bilancio dello stato, inizialmente nullo Stati Uniti Corea Giappone... Francia Germania 1 41 42 3 4 5 6 7 8 Kia BMW Mercedes...... Chevrolet 15 Algoritmo Raccolta delle statistiche import-export: calcolo di sommatorie, dopo aver filtrato i dati Transazioni negative (import) e positive (export) Transazioni per singoli stati Problema di ricerca del massimo, ripetuto per lo stato con massimo import e quello con massimo export 16 26 Politecnico di Torino 8
Scomposizione in sottoproblemi Un primo livello di scomposizione è connesso alla natura del problema Calcolo statistiche import export Ricerca dei massimi Un ulteriore sottoproblema è costituito dalla conversione nome società codice stato che può essere ricondotta a un problema di ricerca nella tabella delle società 17 26 Politecnico di Torino 9
Programma import-export (1/7) #include <stdio.h> #define MAXC 1 /* tipi struct per stati e societa' */ typedef struct { char *nome; int bilancio; t_stato; typedef struct { char *nome; int codice_stato; t_societa; /* prototipo di funzione */ int cercacodicestato( t_societa tab_soc[], int n, char *nome); 19 Programma import-export (2/7) int main (int argc, char *argv[]) { FILE *fp; int nst, nsoc, codice, importo, i, nt, si, se, maxi, maxe; char nome[maxc]; t_stato tab_st[1]; t_societa tab_soc[1]; /* lettura intestazione file F */ fp = fopen(argv[1],"r"); fscanf(fp, %d%d,&nst,&nsoc); /* Inizializzazione nomi */ for (i=; i<1; i++) tab_st[i].nome = NULL; 2 26 Politecnico di Torino 1
Programma import-export (2/7) int main (int argc, char *argv[]) { FILE *fp; int nst, nsoc, codice, importo, i, nt, si, I se, nomi maxi, di stati maxe; sono inizializzati a char nome[maxc]; NULL. I codici con nome NULL dopo t_stato tab_st[1]; la lettura sono non assegnati t_societa tab_soc[1]; /* lettura intestazione file F */ fp = fopen(argv[1],"r"); fscanf(fp, %d%d,&nst,&nsoc); /* Inizializzazione nomi */ for (i=; i<1; i++) tab_st[i].nome = NULL; 21 Programma import-export (3/7) /* lettura tabella stati */ for (i=; i<nst; i++) { fscanf(fp,"%d%s", &codice, nome); tab_st[codice].nome = strdup(nome); tab_st[codice].bilancio = ; /* lettura tabella societa' */ for (i=; i<nsoc; i++) { fscanf(fp,"%d%s", &codice, nome); tab_soc[i].nome = strdup(nome); tab_soc[i].codice_stato = codice; fclose(fp); 22 26 Politecnico di Torino 11
Programma import-export (3/7) /* lettura tabella stati */ for (i=; i<nst; i++) { fscanf(fp,"%d%s", &codice, nome); tab_st[codice].nome = strdup(nome); tab_st[codice].bilancio = ; /* lettura tabella societa' */ for (i=; i<nsoc; i++) { fscanf(fp,"%d%s", Le &codice, informazioni nome); sugli stati sono tab_soc[i].nome = strdup(nome); immagazzinate nella casella avente tab_soc[i].codice_stato = codice; come indice il codice. Il bilancio è fclose(fp); inizializzato a 23 Programma import-export (3/7) Le informazioni /* letturasulle tabella societàstati sono */ immagazzinate for (i=; progressivamente i<nst; i++) { (con indici fscanf(fp,"%d%s", crescenti) &codice, nome); tab_st[codice].nome = strdup(nome); tab_st[codice].bilancio = ; /* lettura tabella societa' */ for (i=; i<nsoc; i++) { fscanf(fp,"%d%s", &codice, nome); tab_soc[i].nome = strdup(nome); tab_soc[i].codice_stato = codice; fclose(fp); 24 26 Politecnico di Torino 12
Programma import-export (4/7) fp = fopen(argv[2],"r"); nt = si = se = ; while (fscanf(fp,"%s%d%*s", nome, &importo)!= EOF) { nt++; if (importo > ) se += importo; else si += importo; codice=cercacodicestato(tab_soc,nsoc,nome); tab_st[codice].bilancio += importo; fclose(fp); 25 Programma import-export (4/7) Filtro sui dati: fp = fopen(argv[2],"r"); nt = si = se = ; se importo > while (fscanf(fp,"%s%d%*s", export nome, altrimenti &importo)!= EOF) { nt++; import if (importo > ) se += importo; else si += importo; codice=cercacodicestato(tab_soc,nsoc,nome); tab_st[codice].bilancio += importo; fclose(fp); 26 26 Politecnico di Torino 13
Programma import-export (4/7) fp = fopen(argv[2],"r"); nt = si = se = ; while (fscanf(fp,"%s%d%*s", nt++; if (importo > ) se += importo; else si += importo; codice=cercacodicestato(tab_soc,nsoc,nome); tab_st[codice].bilancio += importo; fclose(fp); nome, &importo)!= EOF) { Conversione nome-codice, fatta come sottoproblema di ricerca 27 Programma import-export (5/7) /* calcola stati con max. imp.-exp. */ maxi = maxe = -1; for (i=; i<nst; i++) if (tab_st[i].nome!= NULL) { if (tab_st[i].bilancio > ) { if (maxe< tab_st[i].bilancio > tab_st[maxe].bilancio) maxe = i; else if (tab_st[i].bilancio < ) { if (maxi< tab_st[i].bilancio < tab_st[maxi].bilancio) maxi = i; 28 26 Politecnico di Torino 14
Programma import-export (5/7) /* calcola stati con max. imp.-exp. */ maxi = maxe = -1; for (i=; i<nst; i++) if (tab_st[i].nome!= NULL) { if (tab_st[i].bilancio > ) { if (maxe< tab_st[i].bilancio > tab_st[maxe].bilancio) maxe = i; else if (tab_st[i].bilancio < ) { if (maxi< Calcola tab_st[i].bilancio (indice dello) stato con < tab_st[maxi].bilancio) massimo export maxi = i; 29 Programma import-export (5/7) /* calcola stati con max. imp.-exp. */ maxi = maxe = -1; for (i=; i<nst; i++) if (tab_st[i].nome!= NULL) { if (tab_st[i].bilancio > ) { if (maxe< tab_st[i].bilancio > tab_st[maxe].bilancio) maxe = i; else if (tab_st[i].bilancio < ) { if (maxi< tab_st[i].bilancio < tab_st[maxi].bilancio) maxi = i; 3 26 Politecnico di Torino 15
Programma import-export (6/7) /* stampa statistiche globali */ printf("num. transazioni: %d\n", nt); printf("totali imp.-exp.: %d %d\n\n", si, se); /* stampa statistiche per stato */ for (i=; i<nst; i++) if (tab_st[i].nome!= NULL) printf("stato: %-3s BILANCIO: %8d\n", tab_st[i].nome,tab_st[i].bilancio); /* stampa max. import-export */ if (maxe>=) printf( Max. exp -> %s: %d\n", tab_st[maxe].nome,tab_st[maxe].bilancio); if (maxi>=) printf( Max. imp -> %s: %d\n", tab_st[maxi].nome,tab_st[maxi].bilancio); 31 Programma import-export (7/7) int cercacodicestato ( t_societa tab_soc[], int n, char *nome ) { int i; for (i=; i<n; i++) { if (strcmp(tab_soc[i].nome,nome)==) return (tab_soc[i].codice_stato); return -1; 32 26 Politecnico di Torino 16