Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Eliminazione numeri pari da una lista dinamica
Forum - C/C++ - Eliminazione numeri pari da una lista dinamica

Avatar
Chiara87 (Normal User)
Newbie


Messaggi: 8
Iscritto: 04/03/2009

Segnala al moderatore
Postato alle 13:56
Lunedì, 16/03/2009
Ciao!
Dovrei scrivere una funzione che permette di eliminare tutti gli elementi pari da una lista di numeri interi (il cui inserimento termina con 0).

Il problema sta solo nella funzione EliminaPari. Funziona in modo corretto quando la lista inserita inizia con un numero dispari. Se metto però il primo numero pari questo viene saltato e poi gli altri numeri pari vengono eliminati correttamente....
Non riesco però a capire come cancellare il primo elemento se è pari..

Qualcuno mi potrebbe aiutare?! Scusate ma sono alle prime armi con liste e puntatori e sto impazzendo a cercare di capire come eliminare questo primo elemento.. :-|

Grazie ^^
Chiara

Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. #include <malloc.h>
  5.  
  6. typedef struct nl {
  7.         int val;
  8.         struct nl* next;
  9.         } NODOLISTA;
  10.        
  11. int v;
  12.  
  13.  
  14. NODOLISTA *InsertLista (NODOLISTA *l, int v)
  15. {
  16.     if (l == NULL)
  17.     {
  18.        NODOLISTA* t = (NODOLISTA *) malloc(sizeof(NODOLISTA));
  19.        if (t != NULL)
  20.        {
  21.           t->val = v;
  22.           t->next = NULL;
  23.        }
  24.        return t;
  25.     }    
  26.        else
  27.     {
  28.           l->next = InsertLista(l->next, v);
  29.           return l;
  30.     }
  31. }
  32.    
  33.  
  34. NODOLISTA *InsertValore (NODOLISTA *l)
  35. {
  36.       printf("INSERISCI UN VALORE (TERMINI CON 0)");
  37.       scanf ("%d", &v);
  38.      
  39.       if (v == 0)
  40.       printf ("\n\nLISTA->NULL\n\n");
  41.            
  42.       while (v != 0)
  43.       {
  44.       if (v != 0)
  45.       l = InsertLista(l, v);
  46.       scanf ("%d", &v);
  47.       }
  48.       return l;
  49.      
  50.      
  51. }
  52.  
  53. NODOLISTA *EliminaPari (NODOLISTA *l)
  54. {
  55. NODOLISTA *la=l, *lb;
  56.  
  57.  
  58. if (la != NULL)
  59. {
  60.  
  61.      
  62.              while (la->next != NULL)
  63.                     {
  64.                      if (la->next->val % 2 != 0) //dispari//
  65.                      {
  66.                      la = la->next;
  67.                      }                
  68.                      else
  69.                          {
  70.                          lb = la->next;
  71.                          la->next = la->next->next;
  72.                          free(lb);
  73.                          }
  74.                      continue;    
  75.                     }
  76. }
  77. return l;
  78.        
  79. }
  80.  
  81. void StampaLista (NODOLISTA *l)
  82. {
  83.      if (l != NULL)
  84.      {
  85.            printf("%d\n", l->val);
  86.            StampaLista(l->next);
  87.      }
  88. }
  89.  
  90. int main () {
  91.  
  92. NODOLISTA* lInt = NULL;
  93.  
  94. lInt = InsertValore (lInt);
  95.  
  96. lInt = EliminaPari (lInt);
  97.  
  98. StampaLista (lInt);
  99.  
  100. system ("PAUSE");
  101. return 0;
  102.  
  103. }


PM Quote
Avatar
theprogrammer (Normal User)
Guru^2


Messaggi: 2509
Iscritto: 28/01/2009

Segnala al moderatore
Postato alle 14:09
Lunedì, 16/03/2009
Ti faccio solo notare che, nella EliminaPari, il tuo ciclo per il controllo dei valori inizia da

la->next

operando quindi su la->next->val

In questo modo salti SEMPRE il nodo corrente, ovvero quello puntato da

la

il cui valore e'

la->val


- Se le mie risposte non vi soddisfano, ignoratele, altrimenti un "grazie" e' molto gradito ...

"Dai un pesce (programma) a un uomo e lo nutrirai per un giorno. Insegnagli a pescare (programmare) e lo nutrirai per tutta la vita." (niente pappa pronta)
PM Quote
Avatar
Chiara87 (Normal User)
Newbie


Messaggi: 8
Iscritto: 04/03/2009

Segnala al moderatore
Postato alle 14:21
Lunedì, 16/03/2009
si ok, ma quindi cosa dovrei cambiare? Ho provato a metterci un if prima del while in modo tale da cancellare il primo elemento con una free ma mi si blocca sempre... :doubt:

grazie di nuovo

Ultima modifica effettuata da Chiara87 il 16/03/2009 alle 14:21
PM Quote
Avatar
theprogrammer (Normal User)
Guru^2


Messaggi: 2509
Iscritto: 28/01/2009

Segnala al moderatore
Postato alle 15:49
Lunedì, 16/03/2009
Scusa, ma la funzione in questione l'hai scritta tu?

Se l'hai scritta tu, da quello che ti ho detto, dovresti saper apportare le modifiche necessarie ...


- Se le mie risposte non vi soddisfano, ignoratele, altrimenti un "grazie" e' molto gradito ...

"Dai un pesce (programma) a un uomo e lo nutrirai per un giorno. Insegnagli a pescare (programmare) e lo nutrirai per tutta la vita." (niente pappa pronta)
PM Quote
Avatar
Chiara87 (Normal User)
Newbie


Messaggi: 8
Iscritto: 04/03/2009

Segnala al moderatore
Postato alle 16:03
Lunedì, 16/03/2009
Testo quotato

Postato originariamente da theprogrammer:

Scusa, ma la funzione in questione l'hai scritta tu?

Se l'hai scritta tu, da quello che ti ho detto, dovresti saper apportare le modifiche necessarie ...



certo che l'ho scritta io!!

Ho provato ad apportare le modifiche che mi hai detto ma continua a non funzionarmi..

Codice sorgente - presumibilmente C/C++

  1. NODOLISTA *EliminaPari (NODOLISTA *l)
  2. {
  3. NODOLISTA *la=l, *lb;
  4.  
  5.              while (la->next != NULL)
  6.                     {
  7.                        if ((la->val % 2) != 0)
  8.                        {
  9.                           la = la->next;
  10.                        }              
  11.                        else
  12.                            {
  13.                           lb = la->next;
  14.                           la->next = lb->next;
  15.                           free(lb);
  16.                        }
  17.                     }
  18. return l;            
  19.      
  20. }



cosa sbaglio?

PM Quote
Avatar
theprogrammer (Normal User)
Guru^2


Messaggi: 2509
Iscritto: 28/01/2009

Segnala al moderatore
Postato alle 17:00
Lunedì, 16/03/2009
Codice sorgente - presumibilmente C/C++

  1. NODOLISTA * EliminaPari(NODOLISTA *l)
  2. {
  3.         NODOLISTA *canc, *tmp=l;
  4.    
  5.         while(tmp && (tmp->val % 2)==0)
  6.         {
  7.                 l = l->next;
  8.                 free(tmp);
  9.                 tmp = l;
  10.         }
  11.  
  12.         while(tmp)
  13.                 if(tmp->next && (tmp->next->val % 2)==0)
  14.                 {
  15.                         canc = tmp->next;
  16.                         tmp->next = tmp->next->next;
  17.                         free(canc);
  18.                 } else
  19.                         tmp = tmp->next;
  20.        
  21.         return l;
  22. }



- Se le mie risposte non vi soddisfano, ignoratele, altrimenti un "grazie" e' molto gradito ...

"Dai un pesce (programma) a un uomo e lo nutrirai per un giorno. Insegnagli a pescare (programmare) e lo nutrirai per tutta la vita." (niente pappa pronta)
PM Quote
Avatar
Chiara87 (Normal User)
Newbie


Messaggi: 8
Iscritto: 04/03/2009

Segnala al moderatore
Postato alle 17:38
Lunedì, 16/03/2009
Testo quotato

Postato originariamente da Chiara87:

Testo quotato

Postato originariamente da theprogrammer:

Scusa, ma la funzione in questione l'hai scritta tu?

Se l'hai scritta tu, da quello che ti ho detto, dovresti saper apportare le modifiche necessarie ...



certo che l'ho scritta io!!

Ho provato ad apportare le modifiche che mi hai detto ma continua a non funzionarmi..

Codice sorgente - presumibilmente C/C++

  1. NODOLISTA *EliminaPari (NODOLISTA *l)
  2. {
  3. NODOLISTA *la=l, *lb;
  4.  
  5.              while (la->next != NULL)
  6.                     {
  7.                        if ((la->val % 2) != 0)
  8.                        {
  9.                           la = la->next;
  10.                        }              
  11.                        else
  12.                            {
  13.                           lb = la->next;
  14.                           la->next = lb->next;
  15.                           free(lb);
  16.                        }
  17.                     }
  18. return l;            
  19.      
  20. }



cosa sbaglio?




ok perfetto, grazie 1000 :k:!! Ho trovato anche un altro tipo di soluzione facendo uso di un terzo puntatore ausiliario che mi scorre tutti gli elementi pari ad inizio lista!

Codice sorgente - presumibilmente Delphi

  1. NODOLISTA *EliminaPari (NODOLISTA *l)
  2. {
  3.    NODOLISTA *la, *lb, *lc;
  4.    lc = l;
  5.  
  6.    if (lc != NULL)
  7.    {
  8.        while ((lc != NULL) && ((lc->val %2) == 0))
  9.        {
  10.            lc = lc->next;
  11.        }
  12.    }
  13.  
  14.     la = lc;
  15.  
  16.    if (la != NULL)
  17.    {
  18.        while (la->next != NULL)
  19.        {
  20.            if (la->next->val % 2 != 0)
  21.            {
  22.                la = la->next;
  23.            }
  24.            else
  25.            {
  26.                lb = la->next;
  27.                la->next = lb->next;
  28.                free(lb);
  29.            }
  30.        }
  31.    }
  32.    return lc;
  33. }


PM Quote
Avatar
gigisoft (Member)
Guru


Messaggi: 695
Iscritto: 11/10/2008

Segnala al moderatore
Postato alle 12:51
Venerdì, 20/03/2009
Testo quotato

Postato originariamente da theprogrammer:

Codice sorgente - presumibilmente C/C++

  1. NODOLISTA * EliminaPari(NODOLISTA *l)
  2. {
  3.         NODOLISTA *canc, *tmp=l;
  4.    
  5.         while(tmp && (tmp->val % 2)==0)
  6.         {
  7.                 l = l->next;
  8.                 free(tmp);
  9.                 tmp = l;
  10.         }
  11.  
  12.         while(tmp)
  13.                 if(tmp->next && (tmp->next->val % 2)==0)
  14.                 {
  15.                         canc = tmp->next;
  16.                         tmp->next = tmp->next->next;
  17.                         free(canc);
  18.                 } else
  19.                         tmp = tmp->next;
  20.        
  21.         return l;
  22. }





Cosi' dovrebbe essere ancora piu' semplice ( con un solo ciclo while ):

Codice sorgente - presumibilmente Php

  1. NODOLISTA * EliminaPari(NODOLISTA *l)
  2. {
  3.  NODOLISTA *canc, *tmp1 = NULL, tmp2 = l;
  4.  
  5.  while(tmp2)
  6.   {
  7.    if (tmp2->val % 2)==0)
  8.       {
  9.        canc = tmp2;
  10.  
  11.        if (tmp1)
  12.           { tmp1->next = tmp2->next; }
  13.        else
  14.           { l = l->next; }
  15.  
  16.           free(canc);
  17.       }
  18.    else
  19.       { tmp1 = tmp2; }
  20.  
  21.    tmp2 = tmp2->next;
  22.   }
  23.      
  24.  return l;
  25. }



Le cose si fanno per bene o non si fanno affatto
PM Quote