Soluzione esame 15 Giugno 2017
mainGiugno.c
—
C source code,
4 kB (4445 bytes)
Contenuto del file
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h> #define NOME_PRODOTTO 50 // Definizione del prodotto typedef struct _prodotto { char nome[NOME_PRODOTTO]; int numero_scatole; } prodotto; // Rappresentazione di un generico nodo dell'albero binario di ricerca typedef struct _nodo_albero { struct _nodo_albero* padre; prodotto dato; struct _nodo_albero* sinistra; struct _nodo_albero* destra; } nodo_albero; // Comparazione dei due prodotti per nome int compara_prodotti(prodotto p1, prodotto p2) { return strcmp(p1.nome, p2.nome); } // Inserisco il prodotto in maniera ordinata nell'albero e copio il contenuto // della struttura data nodo_albero* inserimento_ordinato(nodo_albero* t, prodotto p) { // Creo un nuovo nodo nodo_albero* nodo = (nodo_albero*)malloc(sizeof(nodo_albero)); // Copio i valori letti dal file strcpy(nodo->dato.nome, p.nome); nodo->dato.numero_scatole = p.numero_scatole; // Inizializzo i puntatori del nodo nodo->sinistra = NULL; nodo->destra = NULL; nodo->padre = NULL; // Salvo la radice nodo_albero* corrente = t; // Controlla che l'albero non sia vuoto if (t == NULL) { // L'albero � vuoto, impostiamo la radice e ritorniamo return nodo; } // Scorri fino a trovare il primo spazio libero nodo_albero* radice = t; // Prima o poi la fine � raggiunta int stop = 0; while (!stop) { int cmp = compara_prodotti(p, corrente->dato); if (cmp == 0) { // I prodotti sono uguali, incrementa il valore delle scatole corrente->dato.numero_scatole += p.numero_scatole; stop = 1; } else { // Se non � finito, spostati al successivo nodo ordinato, se esiste if (cmp < 0) { if (corrente->sinistra) corrente = corrente->sinistra; // Prodotto minore, spostati a sinistra else { // Inserisci qua, spazio libero corrente->sinistra = nodo; nodo->padre = corrente; stop = 1; } } else { if (corrente->destra) corrente = corrente->destra; // Prodotto maggiore, spostati a destra else { // Inserisci qua, spazio libero corrente->destra = nodo; nodo->padre = corrente; stop = 1; } } } } // Restituisci la radice return t; } // Creare un albero binario di ricerca che contiene tutti i dati dei prodotti, senza // duplicati in copia unica come nome e come somma del numero di scatole ordinato in // base al nome del prodotto. Restituisce la radice dell'albero nodo_albero* funzioneA(FILE* f_bin, FILE* f_txt, nodo_albero* t) { // Lettura del file binario prodotto buffer; nodo_albero* radice = t; // Leggi ed inserisci file binario while (fread(&buffer, sizeof(buffer), 1, f_bin)) { // Letto un elemento, inserisco nell'albero t = inserimento_ordinato(t, buffer); } // Leggi ed inserisci file testuale while (!feof(f_txt)) { // Leggo da file di testo l'elemento alla riga corrispondente fscanf(f_txt, "%s %d ", &(buffer.nome), &(buffer.numero_scatole)); t = inserimento_ordinato(t, buffer); } return t; } // Stampare a video il contenuto ordinato dell'albero void funzioneB(nodo_albero* t) { // Parti da sinistra, scorri fino ad arrivare a destra nodo_albero* nodo = (nodo_albero*)t; if (nodo->sinistra) funzioneB(nodo->sinistra); // Stampa il nodo corrente altrimenti � sfasato, prima di andare a destra printf("%s, %d\n", nodo->dato.nome, nodo->dato.numero_scatole); if (nodo->destra) funzioneB(nodo->destra); } // Stampare su file di testo l'albero void funzioneC(nodo_albero* t, FILE* f_out) { // Parti da sinistra, scorri fino ad arrivare a destra nodo_albero* nodo = (nodo_albero*)t; if (nodo->sinistra) funzioneC(nodo->sinistra, f_out); // Stampa il nodo corrente altrimenti � sfasato, prima di andare a destra fprintf(f_out, "%s, %d\n", nodo->dato.nome, nodo->dato.numero_scatole); if (nodo->destra) funzioneC(nodo->destra, f_out); } int main(int argc, char** argv) { // Lettura dai file dati FILE* f_out = fopen("output.txt", "wt"); FILE* f_bin = fopen("elena.bin", "rb"); FILE* f_txt = fopen("marta.txt", "rt"); nodo_albero* t = NULL; // Lettura e creazione dell'albero t = funzioneA(f_bin, f_txt, NULL); // Stampa a video funzioneB(t); // Stampa su file funzioneC(t, f_out); // Chiusura degli handles fclose(f_bin); fclose(f_txt); fclose(f_out); return 0; }