Confronta liste con ricorsione

di il
13 risposte

Confronta liste con ricorsione

Buonasera a tutti,
per esercizio, devo risolvere il seguente problema: devo passare a una funzione due liste e verificare se la prima lista è contenuta nella seconda ricorsivamente. Ho impostato la seguente funzione,
int contenuto(struct insieme *p, struct insieme *p2)
{
    int i=0 , y=0;
    if(p != NULL)
    {
        i = cerca(p2,p->inf);
        y = y + i;
     }
        contenuto(p->pun,p2);
        return (y);
}
oltre a quanto scritto nella funzione dovrei verificare se y==numero elementi della lista 1, allora la lista 1 è contenuta nella lista 2.
però "ovviamente" non funziona, in quanto y, ad ogni ricorsione viene azzerata. Nella funzione riportata sopra ho utilizzato un altra funzione che ho sviluppato "cerca" alla quale passo la lista 2 e... alla prima ricorsione il primo valore della lista 1, alla seconda ricorsione il secondo valore della lista 1... etc finchè non ho scorso tutto la lista 1...

Ad ogni modo, il mio problema è che y viene azzerato... quindi non posso fare quel controllo che dicevo sopra.

Vi ringrazio anticipatamente per l'aiuto.
A presto,
Pippo

13 Risposte

  • Re: Confronta liste con ricorsione

    Ciao!

    Giusto per capire:
    - di che tipo di liste stiamo parlando? Di liste semplicemente concatenate?
    - potresti chiarire meglio cosa intendi con lista contenuta in un'altra?
    - la funzione ricorsiva può avere come argomenti solo le due liste?
    - potresti postare le definizioni della struct insieme e della funzione cerca()?
  • Re: Confronta liste con ricorsione

    Nippolo ha scritto:


    Ciao!

    Giusto per capire:
    - di che tipo di liste stiamo parlando? Di liste semplicemente concatenate?
    - potresti chiarire meglio cosa intendi con lista contenuta in un'altra?
    - la funzione ricorsiva può avere come argomenti solo le due liste?
    - potresti postare le definizioni della struct insieme e della funzione cerca()?
    Ciao!
    - sono due liste di numeri interi
    - esempio Lista1: {1,2,3} Lista 2{1,2,3,4} la lista 1 è contenuta nella lista 2. Tutti gli elementi di lista 1 appartengono a Lista 2.
    - la funzione ricorsiva, esatto può avere come argomenti solo le due liste.
    
    struct insieme {
       int inf;
       struct insieme *pun;
    };
    
    int cerca(struct insieme *p,int x){
        int i = 0;
        if(p == NULL){
            i = 0;
        }else if((p->inf)==x){
            i = 1;
        }else{
            return cerca(p->pun,x);
        }
        return(i);
    }
    
    Grazie mille!
  • Re: Confronta liste con ricorsione

    Pippo ha scritto:


    - esempio Lista1: {1,2,3} Lista 2{1,2,3,4} la lista 1 è contenuta nella lista 2. Tutti gli elementi di lista 1 appartengono a Lista 2.
    Ok, ma quando dici che la lista 1 deve essere contenuta nella lista 2, ti riferisci al fatto che la lista 1 sia una parte della lista 2 come illustrato nella seguente immagine

    oppure intendi semplicemente che la lista 2 deve contenere una successione di nodi caratterizzata da dati (eccetto ovviamente il puntatore al nodo successivo) uguali a quelli della lista 1, come illustrato in quest'altra immagine?
  • Re: Confronta liste con ricorsione

    Nippolo ha scritto:


    Pippo ha scritto:


    - esempio Lista1: {1,2,3} Lista 2{1,2,3,4} la lista 1 è contenuta nella lista 2. Tutti gli elementi di lista 1 appartengono a Lista 2.
    Ok, ma quando dici che la lista 1 deve essere contenuta nella lista 2, ti riferisci al fatto che la lista 1 sia una parte della lista 2 come illustrato nella seguente immagine

    oppure intendi semplicemente che la lista 2 deve contenere una successione di nodi caratterizzata da dati (eccetto ovviamente il puntatore al nodo successivo) uguali a quelli della lista 1, come illustrato in quest'altra immagine?
    ciao, il secondo caso è ciò che intendo. grazie mille.
  • Re: Confronta liste con ricorsione

    Ok. ho capito di dover impostare la funzione ricorsiva in modo differente.
    vi aggiorno, grazie
  • Re: Confronta liste con ricorsione

    RISOLTOOOOOOOOOOOOO !!!!!!!!
  • Re: Confronta liste con ricorsione

    Posta il codice sono curioso!

    EDIT:
    Altra domanda: la lista {1 3 5} è contenuta nella lista {1 2 3 4 5}? Oppure i valori oltre a comparire in ordine devono anche essere consecutivi?
  • Re: Confronta liste con ricorsione

    Nippolo ha scritto:


    Posta il codice sono curioso!

    EDIT:
    Altra domanda: la lista {1 3 5} è contenuta nella lista {1 2 3 4 5}? Oppure i valori oltre a comparire in ordine devono anche essere consecutivi?
    La lista {1 3 5} è contenuta nella lista {1 2 3 4 5}
    int contenuto(struct insieme *p, struct insieme *p2){
    int trovato=0;
    while(p != NULL){
    
        trovato = cerca(p2,p->inf);
        if(trovato==1)
            contenuto(p->pun,p2);
        return(trovato);
    adesso devo sviluppare l'unione di due liste in modo ricorsivo..
  • Re: Confronta liste con ricorsione

    Volevo testare la funzione che hai postato, ma non è completa! Mancano solo le due parentesi graffe finali?

    Invece la lista {1 5 3} non è contenuta nella lista {1 2 3 4 5}, giusto?
  • Re: Confronta liste con ricorsione

    Nippolo ha scritto:


    Volevo testare la funzione che hai postato, ma non è completa! Mancano solo le due parentesi graffe finali?

    Invece la lista {1 5 3} non è contenuta nella lista {1 2 3 4 5}, giusto?
    si scusami mi sono sfuggite le parentesi finali
    per controllare se una lista è contenuta in un'altra non è importante l'ordine degli elementi, basta controllare che tutti gli elementi appartengano all'altra lista. Quindi la lista {1 5 3} è contenuta nella lista {1 2 3 4 5}.
    ciao
  • Re: Confronta liste con ricorsione

    Capisco, invece io mi stavo cimentando nell'implementare una funzione ricorsiva che ricercasse nella lista 2 la sequenza ordinata che costituisce la lista 1... ed effettivamente è un po' più complicato rispetto a controllare l'appartenenza dei vari elementi di una lista all'altra.

    Ipotizzando che la funzione completa sia:
    int contenuto(nodo *p1, nodo *p2)
    {
        int trovato = 0;
        while(p1 != NULL)
        {
            trovato = cerca(p2, p1->dato);
            if(trovato == 1)
            {
                contenuto(p1->next, p2);
            }
            return trovato;
        }
    }
    vorrei fare alcune considerazioni:
    - il ciclo while è inutile e può essere sostituito da un semplice if. Infatti, vista la posizione del return, quel ciclo potrà avere al massimo una sola iterazione;
    - sempre riguardo alla posizione del return... cosa ritorna la funzione nel caso in cui p1==NULL?
    - in ogni caso il problema fondamentale è che la risposta che ti fornisce quella funzione si basa solo sul primo elemento di p1... per esempio il tuo codice mi dice che la lista {7 1 2} non appartiene alla lista {1 2 3 4 5}, mentre la lista {3 6 8} sì.
    Bisogna quindi modificare un po' la funzione, sei d'accordo?
  • Re: Confronta liste con ricorsione

    Nippolo ha scritto:


    Capisco, invece io mi stavo cimentando nell'implementare una funzione ricorsiva che ricercasse nella lista 2 la sequenza ordinata che costituisce la lista 1... ed effettivamente è un po' più complicato rispetto a controllare l'appartenenza dei vari elementi di una lista all'altra.

    Ipotizzando che la funzione completa sia:
    int contenuto(nodo *p1, nodo *p2)
    {
        int trovato = 0;
        while(p1 != NULL)
        {
            trovato = cerca(p2, p1->dato);
            if(trovato == 1)
            {
                contenuto(p1->next, p2);
            }
            return trovato;
        }
    }
    vorrei fare alcune considerazioni:
    - il ciclo while è inutile e può essere sostituito da un semplice if. Infatti, vista la posizione del return, quel ciclo potrà avere al massimo una sola iterazione;
    - sempre riguardo alla posizione del return... cosa ritorna la funzione nel caso in cui p1==NULL?
    - in ogni caso il problema fondamentale è che la risposta che ti fornisce quella funzione si basa solo sul primo elemento di p1... per esempio il tuo codice mi dice che la lista {7 1 2} non appartiene alla lista {1 2 3 4 5}, mentre la lista {3 6 8} sì.
    Bisogna quindi modificare un po' la funzione, sei d'accordo?
    hai ragione... ho sistemato un po' la funzione... al momento è la seguente, anche se non è un gran che...
    int contenuto(struct insieme *p, struct insieme *p2){
    int trovato=0;
    while(p != NULL){
    
        trovato = cerca(p2,p->inf);
        if(trovato==1)
        {
           p=p->pun;
            contenuto(p,p2);
        }
         else if(trovato == 0)
         // else (trovato==0)
          return(trovato);
    }
        return(trovato);
    }
  • Re: Confronta liste con ricorsione

    Dal momento che non ho molta voglia di analizzare in modo approfondito l'ultima funzione che hai postato, non me la sento di assicurarti che quel codice sia perfettamente funzionante!
    In ogni caso mettendo una printf() all'inizio della funzione ho notato che la funzione viene chiamata molte più volte di quelle strettamente necessarie. Per esempio per le liste p1={2, 4, 1} e p2={1, 2, 3, 4, 5} effettua ben 8 chiamate ricorsive, mentre in teoria ne basterebbero 4, poiché il numero massimo di chiamate dovrebbe essere pari al numero di elementi di p1 più 1.
    Secondo me la cosa più semplice sarebbe qualcosa del genere:
    int contenuto(nodo *p1, nodo *p2)
    {
        if(p1)
        {
            if(cerca(p2, p1->dato))
            {
                return contenuto(p1->next, p2);
            }
            return 0;
        }
        return 1;
    }
Devi accedere o registrarti per scrivere nel forum
13 risposte