[Algoritmi]
Salve a tutti. Sto riscontrando alcuni problemi con questo esercizio. Non riesco a risolvere gli errori che si presentano. Qualcuno potrebbe aiutarmi dandomi alcuni suggerimenti? Ringrazio chi mi aiuterà
Nel link che ho postato ci sono le Struct necessiare
https://onlinegdb.com/_2YtSxup1
In allegato ci sono anche gli errori

Nel link che ho postato ci sono le Struct necessiare
https://onlinegdb.com/_2YtSxup1
In allegato ci sono anche gli errori
/* * Una biblioteca deve riorganizzare alcuni elenchi di libri tra cui elenco1 * (un BST), elenco2 (una HT) ed elenco3 (una lista). * In ciascuna struttura un libro e' rappresentato da * un codice ISBN numerico (campo chiave) e da un titolo. * * Si dovra' realizzare un programma che individui tutti i libri presenti in * entrambi gli elenchi, li stampi in ordine crescente di ISBN (completare nella * funzione main) e che sostituisca in elenco2 * il codice ISBN di un libro in base al titolo. * Infine, da elenco3 verranno rimossi tutti i libri con ISBN pari e anche l'elemento * con ISBN piu' piccolo. * Per realizzare tale programma occorre sviluppare le seguenti funzioni. * * 1) BSTHTdupList(bst, ht, list): funzione RICORSIVA che copia in list (lista * ordinata) tutti i libri che sono presenti contemporaneamente sia in bst che * in ht (fa fede il codice ISBN). * * 2) HTchangeKey(ht, value, newKey): funzione ITERATIVA che sostituisce in ht * la chiave associata a value con la nuova chiave newKey. * Se value non e' presente in ht allora non fa nulla. * Se value compare piu' di una volta in ht allora alle fine ci sara' una sola * coppia (newKey, value). Se newKey e' gia' presente in ht allora il vecchio valore * viene rimosso e poi viene inserito il nuovo valore. * * 3) listDeleteEven(list): funzione RICORSIVA che elimina da list tutti i * libri con ISBN pari. Restituisce la lista aggiornata. * * 4) deleteMinList(list): funzione che elimina il libro con ISBN piu' basso. */ #include <stdio.h> #include <string.h> #include "THT.h" #include "TBST.h" #include "TArray.h" #include "TList.h" TList BSTHTdupList(TBST bst, THT *ht, TList list) { //CASO BASE: l'albero è vuoto, niente da aggiungere if(bst != NULL) { //DIVIDE E COMBINA: aggiungo il sotto-albero sinistro (elementi minori) list = BSTHTdupList(bst->left, ht, list); bst->left = BSTHTdupList(bst->left, ht, list); //Aggiungo l'elemento list = listInsert(list, bst->info); //Aggiungo il sotto-albero destro (elementi maggiori) list = BSTHTdupList(bst->right, ht, list); bst->right = BSTHTdupList(bst->right, ht, list); } return list; } void HTchangeKey(THT* ht, TValue value, TKey newKey) { TList list = listCreate(); TNode* node = nodeCreate(list->info); if (list == NULL) return; for (int i = 0; i < ht->n_bucket; i++) for (TNode *node = ht->bucket[i]; node != NULL; node = node->link) if (HTsearch(ht, list->info.key) == NULL) HTinsert(ht, list->info.value, list->info.key); list = listInsert(list,node->info); } TList listDeleteEven(TList list) { /* Caso Base */ if(list == NULL) { return list; } /* Divide et Impera */ TList tail = listDeleteEven(list->link); if(listDeleteEven(list->info)) list->link = tail; else { nodeDestroy(list); list = tail; } /* Combina */ return list; } TList deleteMinList(TList list) { TNode* curr = list; TNode* prev; /* Ricerca degli elementi da cancellare */ while(curr != NULL) { if(infoGreater(curr->info, min) && infoLess(curr->info, max)) { prev = curr; list = listDelete(list, curr->info); curr = prev->link; } else curr = curr->link; } return list; } int main() { TBST elenco1 = BSTcreate(); elenco1 = BSTinsert(elenco1, (TInfo) {1321, "Le mille e una notte"}); elenco1 = BSTinsert(elenco1, (TInfo) {2372, "Orgoglio e pregiudizio"}); elenco1 = BSTinsert(elenco1, (TInfo) {3432, "Finzioni"}); elenco1 = BSTinsert(elenco1, (TInfo) {4223, "Delitto e castigo"}); elenco1 = BSTinsert(elenco1, (TInfo) {1445, "Il processo"}); elenco1 = BSTinsert(elenco1, (TInfo) {2234, "Madame Bovary"}); elenco1 = BSTinsert(elenco1, (TInfo) {1238, "L'amore ai tempi del colera"}); elenco1 = BSTinsert(elenco1, (TInfo) {6643, "Il vecchio e il mare"}); elenco1 = BSTinsert(elenco1, (TInfo) {1111, "Anna Karenina"}); THT* elenco2 = HTcreate(5); HTinsert(elenco2, 3357, (TValue) {"Il rosso e il nero"}); HTinsert(elenco2, 7675, (TValue) {"Alla ricerca del tempo perduto"}); HTinsert(elenco2, 4222, (TValue) {"Moby-Dick"}); HTinsert(elenco2, 1445, (TValue) {"Il processo"}); HTinsert(elenco2, 3233, (TValue) {"Pippi Calzelunghe"}); HTinsert(elenco2, 3321, (TValue) {"L'uomo senza qualita'"}); HTinsert(elenco2, 1111, (TValue) {"Anna Karenina"}); HTinsert(elenco2, 9090, (TValue) {"Le metamorfosi"}); HTinsert(elenco2, 3432, (TValue) {"Finzioni"}); printf("Libri in elenco1 (BST):\n"); BSTprint(elenco1); printf("\nLibri in elenco2 (HT):\n"); HTprint(elenco2); TList elenco3 = listCreate(); printf("\nCopio in elenco3 (lista) i libri contenuti sia in elenco1 che elenco2."); elenco3 = BSTHTdupList (elenco1, elenco2, elenco3); printf("\nLibri in elenco3 in ordine crescente di ISBN:\n"); /* Completare con la chiamata a funzione corretta */ listPrint(elenco3); TValue titolo = (TValue) {"Il processo"}; TKey nuovoISBN = 1000; printf("\nCambio in elenco2 (HT) il codice di '%s' in %d", titolo.titolo, nuovoISBN); HTchangeKey(elenco2, titolo, nuovoISBN); printf("\nLibri in elenco2 dopo la modifica:\n"); HTprint(elenco2); elenco3 = listDeleteEven(elenco3); printf("\nStudenti in elenco3 (Lista)\n(dopo aver rimosso gli ISBN pari)\n"); listPrint(elenco3); elenco3 = deleteMinList(elenco3); printf("\nLibri in elenco3 (Lista)\n(tutti quelli di elenco3 tranne ISBN piu' basso)\n"); listPrint(elenco3); BSTdestroy(elenco1); HTdestroy(elenco2); listDestroy(elenco3); return 0; }


Risposte
Le strutture sono fornite dal professore? Sembra che la hash table sia fatta per memorizzare dati diversi. Nota che un ISBN di un libro è un numero di 13 cifre. Quindi il valore massimo è \(10^{14}-1\) che non può essere salvato in un intero (con segno) a 32 bit. Devi per forza utilizzare un intero (meglio senza segno) a 64 bit. Ti suggerisco di usare il typedef uint64_t fornito nella libreria standard . Non vi è comunque alcun posto per il titolo (si tratta probabilmente di una libreria per un problema diverso).
Nota che listCreate crea un puntatore a NULL, quindi fare link->info dopo averlo chiamato fa crashare il programma.
Le funzioni che hai implementato nel main non fatto quello che viene richiesto, quindi per correggerti il codice dovrei mettermi a riscrivere le tue funzioni e, probabilmente, anche quelle fornite dal professore (che non mi paiono di gran qualità). Non mi sembra il caso.
Comincia a mettere a posto le strutture.
Nota che listCreate crea un puntatore a NULL, quindi fare link->info dopo averlo chiamato fa crashare il programma.
Le funzioni che hai implementato nel main non fatto quello che viene richiesto, quindi per correggerti il codice dovrei mettermi a riscrivere le tue funzioni e, probabilmente, anche quelle fornite dal professore (che non mi paiono di gran qualità). Non mi sembra il caso.
Comincia a mettere a posto le strutture.
https://onlinegdb.com/-Z8uhkELV_ Ho aggiornato il codice

/* * Una biblioteca deve riorganizzare alcuni elenchi di libri tra cui elenco1 * (un BST), elenco2 (una HT) ed elenco3 (una lista). * In ciascuna struttura un libro e' rappresentato da * un codice ISBN numerico (campo chiave) e da un titolo. * * Si dovra' realizzare un programma che individui tutti i libri presenti in * entrambi gli elenchi, li stampi in ordine crescente di ISBN (completare nella * funzione main) e che sostituisca in elenco2 * il codice ISBN di un libro in base al titolo. * Infine, da elenco3 verranno rimossi tutti i libri con ISBN pari e anche l'elemento * con ISBN piu' piccolo. * Per realizzare tale programma occorre sviluppare le seguenti funzioni. * * 1) BSTHTdupList(bst, ht, list): funzione RICORSIVA che copia in list (lista * ordinata) tutti i libri che sono presenti contemporaneamente sia in bst che * in ht (fa fede il codice ISBN). * * 2) HTchangeKey(ht, value, newKey): funzione ITERATIVA che sostituisce in ht * la chiave associata a value con la nuova chiave newKey. * Se value non e' presente in ht allora non fa nulla. * Se value compare piu' di una volta in ht allora alle fine ci sara' una sola * coppia (newKey, value). Se newKey e' gia' presente in ht allora il vecchio valore * viene rimosso e poi viene inserito il nuovo valore. * * 3) listDeleteEven(list): funzione RICORSIVA che elimina da list tutti i * libri con ISBN pari. Restituisce la lista aggiornata. * * 4) deleteMinList(list): funzione che elimina il libro con ISBN piu' basso. */ #include <stdio.h> #include <string.h> #include "THT.h" #include "TBST.h" #include "TArray.h" #include "TList.h" TList BSTHTdupList(TBST bst, THT *ht, TList list) { //CASO BASE: l'albero è vuoto, niente da aggiungere if(bst != NULL) { //DIVIDE E COMBINA: aggiungo il sotto-albero sinistro (elementi minori) list = BSTHTdupList(bst->left, ht, list); bst->left = BSTHTdupList(bst->left, ht, list); //Aggiungo l'elemento list = listInsert(list, bst->info); //Aggiungo il sotto-albero destro (elementi maggiori) list = BSTHTdupList(bst->right, ht, list); bst->right = BSTHTdupList(bst->right, ht, list); } return list; } void HTchangeKey(THT* ht, TValue value, TKey newKey) { TList list = listCreate(); TNode* node = nodeCreate(list->info); if (list == NULL) return; for (int i = 0; i < ht->n_bucket; i++) for (TNode *node = ht->bucket[i]; node != NULL; node = node->link) if (HTsearch(ht, list->info.key) == NULL) HTinsert(ht, list->info.key, list->info.value); list = listInsert(list,node->info); } TList listDeleteEven(TList list) { /* Caso Base */ if(list == NULL) { return list; } /* Divide et Impera */ TList tail = listDeleteEven(list->link); if(listDeleteEven(list->link)) list->link = tail; else { nodeDestroy(list); list = tail; } /* Combina */ return list; } TList deleteMinList(TList list) { TNode* curr = list; TNode* prev; TInfo min, max; /* Ricerca degli elementi da cancellare */ while(curr != NULL) { if(infoGreater(curr->info, min) && infoLess(curr->info, max)) { prev = curr; list = listDelete(list, curr->info); curr = prev->link; } else curr = curr->link; } return list; } int main() { TBST elenco1 = BSTcreate(); elenco1 = BSTinsert(elenco1, (TInfo) {1321, "Le mille e una notte"}); elenco1 = BSTinsert(elenco1, (TInfo) {2372, "Orgoglio e pregiudizio"}); elenco1 = BSTinsert(elenco1, (TInfo) {3432, "Finzioni"}); elenco1 = BSTinsert(elenco1, (TInfo) {4223, "Delitto e castigo"}); elenco1 = BSTinsert(elenco1, (TInfo) {1445, "Il processo"}); elenco1 = BSTinsert(elenco1, (TInfo) {2234, "Madame Bovary"}); elenco1 = BSTinsert(elenco1, (TInfo) {1238, "L'amore ai tempi del colera"}); elenco1 = BSTinsert(elenco1, (TInfo) {6643, "Il vecchio e il mare"}); elenco1 = BSTinsert(elenco1, (TInfo) {1111, "Anna Karenina"}); THT* elenco2 = HTcreate(5); HTinsert(elenco2, 3357, (TValue) {"Il rosso e il nero"}); HTinsert(elenco2, 7675, (TValue) {"Alla ricerca del tempo perduto"}); HTinsert(elenco2, 4222, (TValue) {"Moby-Dick"}); HTinsert(elenco2, 1445, (TValue) {"Il processo"}); HTinsert(elenco2, 3233, (TValue) {"Pippi Calzelunghe"}); HTinsert(elenco2, 3321, (TValue) {"L'uomo senza qualita'"}); HTinsert(elenco2, 1111, (TValue) {"Anna Karenina"}); HTinsert(elenco2, 9090, (TValue) {"Le metamorfosi"}); HTinsert(elenco2, 3432, (TValue) {"Finzioni"}); printf("Libri in elenco1 (BST):\n"); BSTprint(elenco1); printf("\nLibri in elenco2 (HT):\n"); HTprint(elenco2); TList elenco3 = listCreate(); printf("\nCopio in elenco3 (lista) i libri contenuti sia in elenco1 che elenco2."); elenco3 = BSTHTdupList (elenco1, elenco2, elenco3); printf("\nLibri in elenco3 in ordine crescente di ISBN:\n"); /* Completare con la chiamata a funzione corretta */ listPrint(elenco3); TValue titolo = (TValue) {"Il processo"}; TKey nuovoISBN = 1000; printf("\nCambio in elenco2 (HT) il codice di '%s' in %d", titolo, nuovoISBN); HTchangeKey(elenco2, titolo, nuovoISBN); printf("\nLibri in elenco2 dopo la modifica:\n"); HTprint(elenco2); elenco3 = listDeleteEven(elenco3); printf("\nStudenti in elenco3 (Lista)\n(dopo aver rimosso gli ISBN pari)\n"); listPrint(elenco3); elenco3 = deleteMinList(elenco3); printf("\nLibri in elenco3 (Lista)\n(tutti quelli di elenco3 tranne ISBN piu' basso)\n"); listPrint(elenco3); BSTdestroy(elenco1); HTdestroy(elenco2); listDestroy(elenco3); return 0; }


"vict85":
Le strutture sono fornite dal professore? Sembra che la hash table sia fatta per memorizzare dati diversi. Nota che un ISBN di un libro è un numero di 13 cifre. Quindi il valore massimo è \(10^{14}-1\) che non può essere salvato in un intero (con segno) a 32 bit. Devi per forza utilizzare un intero (meglio senza segno) a 64 bit. Ti suggerisco di usare il typedef uint64_t fornito nella libreria standard. Non vi è comunque alcun posto per il titolo (si tratta probabilmente di una libreria per un problema diverso).
Nota che listCreate crea un puntatore a NULL, quindi fare link->info dopo averlo chiamato fa crashare il programma.
Le funzioni che hai implementato nel main non fatto quello che viene richiesto, quindi per correggerti il codice dovrei mettermi a riscrivere le tue funzioni e, probabilmente, anche quelle fornite dal professore (che non mi paiono di gran qualità). Non mi sembra il caso.
Comincia a mettere a posto le strutture.
E' stato tutto fornito dal professore, l'esercizio richiede di implementare le funzioni e di completare con la chiamata a funzione corretta
Al di là dell'ISBN che tanto lui non ha messo come vero ISBN, direi che devi fare questa modifica in TInfo.h:
Convertire
in
O puoi anche tenere 20, ma immagino i titoli siano più lunghi dei nomi e cognomi.
Devi anche cambiare infoPrint, altrimenti non compila.
Riguardo a BSTHTdupList conviene prima fare la parte destra e poi la sinistra perché almeno inserisci i nuovi elementi all'inizio invece che alla fine della lista. Insomma così:
Mancava totalmente la ricerca dell'elemento in ht. Fare destra -> centro -> sinistra è per ottimizzare gli inserimenti supponendo che sinistra < centro < destra.
Per quanto riguarda HTchangeKey, io farei così:
[list=1][*:3eb1em25] elimina tutte le occorrenze di value in ht e contale[/*:m:3eb1em25]
[*:3eb1em25] se il numero di eliminazioni è 0, allora ritorni[/*:m:3eb1em25]
[*:3eb1em25] elimina l'elemento associato a newKey se presente[/*:m:3eb1em25]
[*:3eb1em25] aggiungi (newKey, value).[/*:m:3eb1em25][/list:o:3eb1em25]
Il tutto non può essere fatto con le funzioni fornite dal professore (tranne eliminare l'elemento associato a newKey). Sinceramente la libreria che ha scritto il professore è poco adatta ai problemi che vuole risolvere.
In listDeleteEven(list) non capisco cosa tu voglia fare. Insomma io farei così:
[list=1][*:3eb1em25] Se list è nulla, ritorna NULL[/*:m:3eb1em25]
[*:3eb1em25] Se il key è pari, allora ritorna listDeleteEven(list->link). Insomma elimini la testa.[/*:m:3eb1em25]
[*:3eb1em25] Nel restante di casi, list->link = listDeleteEven(list->link);[/*:m:3eb1em25]
[*:3eb1em25]Infine ritorni list[/*:m:3eb1em25][/list:o:3eb1em25]
Convertire
typedef struct { char nome[20]; char cognome[20]; } TValue;
in
typedef struct { char titolo[40]; } TValue;
O puoi anche tenere 20, ma immagino i titoli siano più lunghi dei nomi e cognomi.
Devi anche cambiare infoPrint, altrimenti non compila.
Riguardo a BSTHTdupList conviene prima fare la parte destra e poi la sinistra perché almeno inserisci i nuovi elementi all'inizio invece che alla fine della lista. Insomma così:
TList BSTHTdupList(TBST bst, THT *ht, TList list) { //CASO BASE: l'albero è vuoto, niente da aggiungere if (bst == NULL) { return list; } list = BSTHTdupList(bst->right, ht, list); TValue *found = HTsearch(ht, bst->info.key); if (found != NULL) { list = listInsert(list, bst->info); // verra' inserito all'inizio } return BSTHTdupList(bst->left, ht, list); }
Mancava totalmente la ricerca dell'elemento in ht. Fare destra -> centro -> sinistra è per ottimizzare gli inserimenti supponendo che sinistra < centro < destra.
Per quanto riguarda HTchangeKey, io farei così:
[list=1][*:3eb1em25] elimina tutte le occorrenze di value in ht e contale[/*:m:3eb1em25]
[*:3eb1em25] se il numero di eliminazioni è 0, allora ritorni[/*:m:3eb1em25]
[*:3eb1em25] elimina l'elemento associato a newKey se presente[/*:m:3eb1em25]
[*:3eb1em25] aggiungi (newKey, value).[/*:m:3eb1em25][/list:o:3eb1em25]
Il tutto non può essere fatto con le funzioni fornite dal professore (tranne eliminare l'elemento associato a newKey). Sinceramente la libreria che ha scritto il professore è poco adatta ai problemi che vuole risolvere.
In listDeleteEven(list) non capisco cosa tu voglia fare. Insomma io farei così:
[list=1][*:3eb1em25] Se list è nulla, ritorna NULL[/*:m:3eb1em25]
[*:3eb1em25] Se il key è pari, allora ritorna listDeleteEven(list->link). Insomma elimini la testa.[/*:m:3eb1em25]
[*:3eb1em25] Nel restante di casi, list->link = listDeleteEven(list->link);[/*:m:3eb1em25]
[*:3eb1em25]Infine ritorni list[/*:m:3eb1em25][/list:o:3eb1em25]
Grazie mille mi metto subito al lavoro
Consigli preziosi

https://onlinegdb.com/U6cdSa1zZ Ho riscritto le funzioni come me le hai consigliate ma ancora non funzionano :/