12/12/10 14:50
WinstonS
Ciao a tutti, starei facendo questo esercizio:
Ora credo di aver risolto tutto, ma se nella funzione del punto iii (EliminaSchedeNulle()) uso f (parametro) al posto di first (puntatore dichiarato globalmente per comodità nel momento in cui vado a stampare la lista ho elementi in più che non dovrebbero esserci (se ho capito bene perchè first viene passato alla funzione per valore);
Quindi sostanzialmente la domanda è questa: cosa devo modificare nel codice per fare in modo che quando cambio il valore di f (cioè l'indirizzo dell'inizio della lista) nella funzione, venga cambiato anche il valore di first? Come posso, cioè, passare per riferimento first a EliminaSchedeNulle()?
Ecco il link al codice: pastebin.com/…
A Elettrolandia si va a votare per eleggere il nuovo Governatore. Si presentano quattro candidati: 1,2,3,4.
Le schede votate sono raccolte in una lista, in cui ogni elemento memorizza il numero del candidato votato e un'informazione
sulla validità della scheda (valida o nulla). Si deve procedere allo spoglio.
(i) Definire gli opportuni tipi di dato per rappresentare la lista delle schede votate
(ii) Progettare una funzione ricorsiva che, presa in input la lista delle schede votate, e un numero corrispondente
ad uno dei candidati, proceda al conteggio dei voti validi relativi a quel candidato
(iii) Progettare una funzione che, presa in input la lista delle schede votate, e il numero corrispondente ad uno dei candidati,
elimini dalla lista iniziale le schede votate non valide di quel
candidato e restituisca il numero di cancellazioni effettuate
Le schede votate sono raccolte in una lista, in cui ogni elemento memorizza il numero del candidato votato e un'informazione
sulla validità della scheda (valida o nulla). Si deve procedere allo spoglio.
(i) Definire gli opportuni tipi di dato per rappresentare la lista delle schede votate
(ii) Progettare una funzione ricorsiva che, presa in input la lista delle schede votate, e un numero corrispondente
ad uno dei candidati, proceda al conteggio dei voti validi relativi a quel candidato
(iii) Progettare una funzione che, presa in input la lista delle schede votate, e il numero corrispondente ad uno dei candidati,
elimini dalla lista iniziale le schede votate non valide di quel
candidato e restituisca il numero di cancellazioni effettuate
Ora credo di aver risolto tutto, ma se nella funzione del punto iii (EliminaSchedeNulle()) uso f (parametro) al posto di first (puntatore dichiarato globalmente per comodità nel momento in cui vado a stampare la lista ho elementi in più che non dovrebbero esserci (se ho capito bene perchè first viene passato alla funzione per valore);
Quindi sostanzialmente la domanda è questa: cosa devo modificare nel codice per fare in modo che quando cambio il valore di f (cioè l'indirizzo dell'inizio della lista) nella funzione, venga cambiato anche il valore di first? Come posso, cioè, passare per riferimento first a EliminaSchedeNulle()?
Ecco il link al codice: pastebin.com/…
#include <stdio.h> #include <stdlib.h> typedef enum {false, true} boolean; struct nodo { int candidato; boolean valida; struct nodo *next; }; typedef struct nodo scheda; scheda *first; //puntatore al primo elemento della lista /* prototipi delle funzioni */ void InizializzaLista(); void AggiungiScheda(int candidato, boolean validita); void ScriviSchede(); int ConteggioVotiValidi(int candidato, scheda* f); int EliminaSchedeNulle(int candidato, scheda *f); /* ## */ int main() { //Variabili varie: int scelta; //Per la scelta del menu int candidato; //tiene un intero 1<=n<=4 riferito al candidato n int validita;//validità della scheda int jolly; int termina=0; InizializzaLista(); while(termina==0){ //Presento un menu di scelta printf("\n\n\nElezioni del nuovo Governatore di Elettolandia\n I candidati sono: '1', '2', '3', '4'\n"); printf("Scegli fra le seguenti opzioni:\n\ 1) Aggiungi scheda\n\ 2) Vedi schede\n\ 3) Svuota Lista Schede\n\ 4) Conteggia Voti validi per un candidato\n\ 5) Elimina schede nulle per un candidato\n\ 6) Termina\n"); //Faccio in modo che l'utente scelga un n 1<=n<=6 prima di continuare l'esecuzione do { printf("\nDigita la tua scelta: ");scanf("%d",&scelta); } while (scelta < 1 || scelta >6); switch (scelta) { case 1: //scelta==1 printf("\nVoto per il candidato numero: ");scanf("%d",&candidato); printf("\nScrivi 0 se la scheda è nulla, 1 se valida: ");scanf("%d",&validita); AggiungiScheda(candidato, validita); printf("Aggiunto un nuovo voto %s per il candidato %d\n\ Premere invio per continuare...", \ first->valida?("valido"):("NON valido"), first->candidato); getchar(); getchar(); break; case 2: printf("** Inizio della lista **\n\ Indirizzo - Candidato - Validità - Successiva\n"); ScriviSchede(); printf("** Fine della lista **\n\ Premere invio per continuare...");getchar();getchar(); break; case 3: InizializzaLista(); printf("Lista svuotata!\nPremere un tasto per continuare");getchar();getchar(); break; case 4: printf("\nInserire il numero del candidato di cui conteggiare i voti validi:");scanf("%d",&candidato); jolly=ConteggioVotiValidi(candidato,first); printf("\nI voti validi per il candidato %d sono: %d",candidato,jolly); printf("\nPremi invio per continuare...");getchar();getchar(); break; case 5: printf("\nInserire il numero del candidato di cui eliminare i voti nulli:");scanf("%d",&candidato); jolly=EliminaSchedeNulle(candidato,first); printf("\nEliminate %d schede",jolly); printf("\nPremi invio per continuare...");getchar();getchar(); break; case 6: termina=1; } } return (0); } //Inizializzazione della lista: si libera la memoria sfruttata precedentemente per la lista void InizializzaLista() { scheda *temp; while (first!=NULL) { temp = first; first = first->next; free(temp); } //first=(scheda*) malloc(sizeof(scheda)); return; } //Funzione per l'aggiunta di schede alla lista void AggiungiScheda(int candidato, boolean validita) { scheda *nuova; nuova = (scheda*) malloc(sizeof(scheda)); nuova->candidato=candidato; nuova->valida=validita; nuova->next=first; first=nuova; return; } //Stampa la lista void ScriviSchede() { scheda *temp=first; while (temp!=NULL) { printf("%p %d - %d %p \n",temp,temp->candidato,temp->valida,temp->next); temp=temp->next; } } //Punto (ii) int ConteggioVotiValidi (int candidato, scheda* f) //sto passando come parametro la lista solo perchè è richiesto esplicitamente nell'esercizio, ne farei a meno sfruttando il puntatore first che è dichiarato globalmente { if (f==NULL) return 0; //controlla che la lista non sia vuota if (f->candidato==candidato && f->valida==true) return 1+ConteggioVotiValidi(candidato, f->next); else return 0+ConteggioVotiValidi(candidato,f->next); } //Fine Punto (ii) // punto (iii) int EliminaSchedeNulle(int candidato, scheda *f) //vedi commento a riga 132 { if (first == NULL) return 0; //Se la lista è vuota esce dalla funzione tornando 0 if (first->next==NULL && first->candidato==candidato && first->valida==false) {InizializzaLista(); return 1;} //Nel caso in cui ci sia un solo elemento nella lista e questo elemento va eliminato, è necessario chiamare inizializzalista(); torna 1 perchè è coem fare una cancellazione int cancellazioni=0; scheda *temp, *prec; //Il primo ciclo fa in modo che f non sia un voto nullo al candidato passato come parametro while (first->candidato==candidato && first->valida==false) { //fin quando la prima scheda è un voto nullo a candidato temp=first->next; //il primo elemento diviene quello successivo free(first); //libero la memoria del vecchio primo elemento first=temp; cancellazioni++; //incremento il numero di cancellazioni } prec=first; //ho gia verificato che f non è una scheda nulla a candidato temp=prec->next; //controllo della scheda successiva alla prima "rimasta" while(temp!=NULL) { if (temp->candidato==candidato && temp->valida==false) { prec->next=temp->next; //Se la scheda puntata da temp non è valida allora la scheda precedente a temp (con prec->next=temp) dovrà puntare alla scheda successiva a temp (temp->next) free(temp); //Libero la memoria cancellazioni++; //incremento il numero di cancellazioni temp=prec->next; } else { prec=temp; //incremento prec temp=temp->next; //incremento temp } }; return cancellazioni; //torna in output il numero delle cancellazioni effettuate } // punto (iii)
Ultima modifica effettuata da WinstonS 12/12/10 21:49
aaa