Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 17
  1. #1
    Utente di HTML.it
    Registrato dal
    Aug 2012
    Messaggi
    25

    Eliminare elementi di posto pari in lista

    Salve a tutti! Sto provando a svolgere un esercizio in cui si chiede di eliminare da una lista gli elementi di posto pari (o dispari). Il codice che ho scritto è il seguente:

    codice:
    void lista::eliminapari(){
        nodo *p;
        int n=0;
           if (l==0)
               cout<<"La lista è vuota";
        else
        
         while(l!=0){   
            if (n%2==0){
            p=l;
            l=l->succ;
            delete p;
            cout<<"#";
            n++;
            cout<<n;
            }
            else
            n++;}
                      
    }
    Ho messo i cout<<n e cout<<# per tentare di capire cosa facesse! Dati 3 elementi l'output è questo: #1#3#5, e mi restituisce sempre la lista vuota! P.S: l è il nodo della classe lista. Dove sbaglio??
    Grazie!

  2. #2

    Moderazione

    Il linguaggio di riferimento va indicato nel titolo come "tag", qui correggo io, in futuro ricordatene.
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    Utente di HTML.it L'avatar di boots
    Registrato dal
    Oct 2012
    Messaggi
    1,626
    l=l->succ;

    Se l è il nodo radice della tua lista, non dovresti mai modificarlo. Nel tuo codice, alla fine del ciclo while l sarà uguale, se hai costruito bene la lista, a null (il succ dell'ultimo elemento)
    usa una variabile di appoggio per il while, tipo

    nodo* tmp_l = l;

  4. #4
    Utente di HTML.it
    Registrato dal
    Aug 2012
    Messaggi
    25
    Ho provato, ma non funziona comunque! Sbaglio sicuramente qualcosa nella struttura.
    Inoltre, come fa l'ultimo elemento a puntare a null? Se è di posto pari deve essere eliminato, ed il precedente deve puntare a null

  5. #5

    Re: Eliminare elementi di posto pari in lista

    Originariamente inviato da swurzy
    Salve a tutti[...]

    Ho messo i cout<<n e cout<<# per tentare di capire cosa facesse! Dati 3 elementi l'output è questo: #1#3#5, e mi restituisce sempre la lista vuota! P.S: l è il nodo della classe lista. Dove sbaglio??
    codice:
    void lista::eliminapari(){
        nodo *p;
        int n=0;
           if (l==0)
               cout<<"La lista è vuota";
        else          //a che serve sto else?? se l ==0 lui comunque non entra nel while
        
         while(l!=0){   
            if (n%2==0){
            p=l;
            l=l->succ;     //l è il successivo rispetto all'ultimo ingresso in questo scope
            delete p;
            cout<<"#";
            n++;
            cout<<n;
            }
            else
            n++;}
                      
    }
    tu ogni volta che rientri nello scope nel quale n è pari chiami l=l->succ cioè incrementi l di uno, quindi non cancelli i dispari, li cancelli in modo consecutivo: infatti il tuo output di n è:
    Dati 3 elementi l'output è questo: #1#3#5
    n "supera" il numero di elementi, ma fa capire che quello scope viene chiamato n_elementi volte e l'errore è proprio qui

  6. #6
    Utente di HTML.it L'avatar di boots
    Registrato dal
    Oct 2012
    Messaggi
    1,626
    Originariamente inviato da swurzy
    Ho provato, ma non funziona comunque! Sbaglio sicuramente qualcosa nella struttura.
    Inoltre, come fa l'ultimo elemento a puntare a null? Se è di posto pari deve essere eliminato, ed il precedente deve puntare a null
    Io ti volevo semplicemente dire che se l è il tuo unico puntatore alla testa della lista, allora non dovresti modificarlo (a meno che non vuoi eliminare il primo elemento)

    poi ci sono altri problemi, tipo quello che dice MegaAlchimista
    Inoltre per eliminare un elemento in una data posizione ti serve anche il suo predecessore, cosa che non mi pare tu abbia.

    Io invece ti suggerirei di eliminare semplicemente il successore del'elemento corrente, tipo:

    codice:
    q = l; 
    while(q){
        node = q->succ;
        if(node){
           q->succ = node->succ;
           delete node;
        }
        q = q->succ;
     }

  7. #7
    Utente di HTML.it
    Registrato dal
    Aug 2012
    Messaggi
    25
    No, infatti non dispongo di un puntatore al predecessore! Sto provando a modificare il codice ma non funziona!
    Il primo elemento ha posizione 0, e quindi deve eliminarlo! Poi c'è il problema legato all'ultimo elemento: se ha posizione pari deve eliminarlo, e quindi il precedente dovrà puntare a 0.

  8. #8
    Utente di HTML.it L'avatar di boots
    Registrato dal
    Oct 2012
    Messaggi
    1,626
    Chiaramente il codice che ho postato non funziona se consideri la posizione che parte da 0
    (però basta che cancelli a botta sicura il primo elemento e poi lo applichi e va )

    Tornando al tuo di sistema, per il predecessore basta che ti tieni un puntatore un passo indietro

    codice:
    pred = curr = l;
    
    while(curr){
        if(n%2==0){
            //fai la cancellazione di curr, tenendo presente che per n==0, l deve essere aggiornato
            //pred->succ punterà a curr->succ
            curr=pred;
        }
        pred = curr;
        curr = curr->succ;
        n++;
    }

  9. #9
    Utente di HTML.it
    Registrato dal
    Aug 2012
    Messaggi
    25
    Ho modificato il codice in questo modo:

    codice:
    void lista::eliminapari(){
        nodo *p, *del;
        int n=0;
        p=l;
        
        if (l==0)
               cout<<"La lista è vuota";
            
         while(p!=0){        //Scorro la lista   
            
             if (n%2==0 && n==0 ){      //Devo eliminare il primo elemento:
                 del=p;
                 p=p->succ;
                 l=p;
                 delete del;
                 cout<<"0 elemento cancellato\n";
             n++;}
             
             else if (n%2==0 && n!=0){     //Se n è pari
                 
                 del=p->succ; 
                 p->succ=p->succ->succ;
                 
            delete del;        //Elimino l'elemento
            cout<<n<<"elemento cancellato\n";
            n++;
            }
            else  
            
            p=p->succ;       //Passo all'elemento successivo
            n++;}            //Incremento n

    dando in input 4 elementi l'output è questo:

    0 elemento cancellato
    2elemento cancellato
    4elemento cancellato
    Exception: STATUS_ACCESS_VIOLATION at eip=00401E29
    eax=00000000 ebx=00000000 ecx=00000004 edx=00000001 esi=61276520 edi=611A1E9F
    ebp=0028AC18 esp=0028ABF0 program=C:\Users\WORK\Desktop\UNICAS\Programmazion e a Oggetti\esami oop\23giugno2009 da RIvedere\dist\Debug\Cygwin_4.x-Windows\23giugno2009_da_rivedere.exe, pid 2412, thread main
    cs=0023 ds=002B es=002B fs=0053 gs=002B ss=002B
    Stack trace:
    Frame Function Args
    0028AC18 00401E29 (0028AC44, 0028AC48, 0028AC48, 5AD07A45)
    0028AC68 0040144C (00000001, 0028AC90, 80010100, 612765F0)
    0028ACF8 6100763A (00000000, 0028CD78, 61006C50, 00000000)
    End of stack trace

    RUN FAILED (exit value 1, total time: 9s)

    Se modifico la clausola del ciclo while e anzichè while(p) dico while (p->succ) non mi da errore, ma ovviamente non cancella l'ultimo elemento se è pari.
    help!!!

  10. #10
    Utente di HTML.it L'avatar di boots
    Registrato dal
    Oct 2012
    Messaggi
    1,626
    Guarda, io l'ho compilato facendo questa modifica (le parentesi nel'else):

    codice:
    void lista::eliminapari(){
        nodo *p, *del;
        int n=0;
        p=l;
        
        if (l==0)
               cout<<"La lista è vuota";
            
         while(p!=0){        //Scorro la lista   
            
             if (n%2==0 && n==0 ){      //Devo eliminare il primo elemento:
                 del=p;
                 p=p->succ;
                 l=p;
                 delete del;
                 cout<<"0 elemento cancellato\n";
             n++;}
             
             else if (n%2==0 && n!=0){     //Se n è pari
                 
                 del=p->succ; 
                 p->succ=p->succ->succ;
                 
            delete del;        //Elimino l'elemento
            cout<<n<<"elemento cancellato\n";
            n++;
            }
            else  {
            
                p=p->succ;       //Passo all'elemento successivo
                n++;                //Incremento n
           } 
    }
    Così non da errori, ma in realtà non cancella i nodi pari... tra l'altro non ho capito cosa vuoi fare nel else if

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.