[C]Cosa sbaglio in questa implementazione?
Ragazzi salve a tutti sto facendo quest' esercizio
Il mio problema è questo: se per esempio la lunghezza della lista è 4, e io inserisco i valori 1,2,3,4 allora mi viene restituito il valore 3 e non 4. Se invece inserisco i valori 1,1,1,1 mi va in crash il programma. Io penso che l'errore sia nei cicli while. Cosa posso fare? cosa mi consigliate? Se c'è l'errore me lo potreste spiegare? grazie per le eventuali risposte.
/*Scrivere il codice di una funzione C che permetta di contare il numero di valori diversi inseriti in una lista di interi.*/ #include<stdio.h> #include<stdlib.h> typedef struct nodo{ int info; struct nodo *next; }Nodo; Nodo *crea_lista(); void stampa_lista(Nodo *); int controlla(Nodo *); int main(){ int num; Nodo *lista; lista=crea_lista(); stampa_lista(lista); num = controlla(lista); printf("Il numero di valori diversi e': %d\n",num); system("pause"); return 0; } Nodo *crea_lista(){ Nodo *p; Nodo *successivo; int i,n; printf("Quanti elementi si vogliono inserire \n"); scanf("%d",&n); if(n==0) p=NULL; else{ p =(Nodo*)calloc(n,sizeof(Nodo)); printf("Inserisci il primo valore\n"); scanf("%d",&p->info); successivo = p; for(i=2;i<=n;++i){ successivo->next=(Nodo*)malloc(sizeof(Nodo)); successivo = successivo->next; printf("Inserisci l'elemento numero %d\n", i); scanf("%d",&successivo->info); } successivo->next=NULL; } return(p); } void stampa_lista(Nodo *p){ printf("nlista--->"); while(p!=NULL){ printf("%d",p->info); printf("--->"); p = p->next; } printf("\n"); return; } int controlla(Nodo *p){ Nodo *successivo; successivo=p; int cnt=0; while(successivo->next!=NULL){ if(p->info == successivo->next->info){ while(p->info == successivo->next->info){ cnt+=0; successivo = successivo->next; }} else{ cnt+=1; successivo = successivo->next; }} return(cnt); }
Il mio problema è questo: se per esempio la lunghezza della lista è 4, e io inserisco i valori 1,2,3,4 allora mi viene restituito il valore 3 e non 4. Se invece inserisco i valori 1,1,1,1 mi va in crash il programma. Io penso che l'errore sia nei cicli while. Cosa posso fare? cosa mi consigliate? Se c'è l'errore me lo potreste spiegare? grazie per le eventuali risposte.
Risposte
Non ho letto il tuo codice bene, ma non capisco perchè usi delle liste a nodi.
Se il problema è quello enunciato nella prima riga, io farei così:
- Creo un semplice array con i valori da analizzare.
- Per ogni valore dell'array eseguo l'istruzione Conta[valore]++, dove conta è un secondo array inizialmente vuoto.
- Poi prendo l'array Conta, lo scorro tutto e ogni volta che incontro un elemento >0, incremento una variabile.
- Alla fine la variabile mi fornisce il numero dei valori diversi.
- Fare attenzione a contare/ non contare lo zero...
Se il problema è quello enunciato nella prima riga, io farei così:
- Creo un semplice array con i valori da analizzare.
- Per ogni valore dell'array eseguo l'istruzione Conta[valore]++, dove conta è un secondo array inizialmente vuoto.
- Poi prendo l'array Conta, lo scorro tutto e ogni volta che incontro un elemento >0, incremento una variabile.
- Alla fine la variabile mi fornisce il numero dei valori diversi.
- Fare attenzione a contare/ non contare lo zero...
Quindi in pratica mi consigli di fare una lista di vettori??
"fk16":
Ragazzi salve a tutti sto facendo quest' esercizio
/*Scrivere il codice di una funzione C che permetta di contare il numero di valori diversi inseriti in una lista di interi.*/
Adesso non ho il tempo di entrare nei dettagli, ma faccio qualche osservazione generale: in generale il bello delle linked list e' che le puoi allocare un pezzo per volta. Se intendi usare le linked list, la funzione "crea_lista" deve creare solo uno "stub", non tutta la lista coma hai fatto tu, mentre per inserire nuovi elementi fai una funzione che alloca un nuovo nodo, lo collega al resto della lista, e inserisce nel nuovo nodo i dati che ti servono (nel tuo caso un intero). Il che ti evita pure di fare svariati errori quando devi contare gli elementi.
In generale lavorando con le linked list e' molto comodo usare la ricorsione a go-go.
Piu' tardi, quando ho un po' di tempo, cerco di dare un'occhiata al tuo sorgente.
"fk16":
Ragazzi salve a tutti sto facendo quest' esercizio
/*Scrivere il codice di una funzione C che permetta di contare il numero di valori diversi inseriti in una lista di interi.*/
Il mio problema è questo: se per esempio la lunghezza della lista è 4, e io inserisco i valori 1,2,3,4 allora mi viene restituito il valore 3 e non 4. Se invece inserisco i valori 1,1,1,1 mi va in crash il programma. Io penso che l'errore sia nei cicli while. Cosa posso fare? cosa mi consigliate? Se c'è l'errore me lo potreste spiegare? grazie per le eventuali risposte.
Prima di tutto una nota: quando devi iterare su linked list non devi solo controllare se il puntatore al successivo e' non nullo, ma anche se il puntatore al nodo corrente lo e'. Nella funzione controlla ci sono un paio di punti in cui cio' non accade.
Comunque, anche se aggiusti quello (non ci vuole poi molto), l'algoritmo resta sbagliato (per questo i risultati sono errati).
Se vuoi per forza utilizzare le linked list, ti suggerisco di lavorarci ricorsivamente.
L'idea e' questa:
sei all'inizio della lista;
controlla se l'elemento in testa e' presente nella coda della lista (questo passo e' piuttosto costoso);
se lo e', ignoralo;
se non lo e', aggiorna il contatore (hai trovato un elemento unico);
prendi come testa della lista il successore del nodo corrente, e ricorri.
Vedi se riesci a risolvere con questo input, semmai chiedi (anche questa e' una tecnica ricorsiva

Nota: invece delle linked list puoi usare strutture dati piu' sofisticate, ma per un esercizio suppongo non sia necessario...