RISOLTO Lista collegata con puntatori

Stato
Discussione chiusa ad ulteriori risposte.

FraFut

Nuovo Utente
5
0
Salve dovre creare qusto programma in linguaggio C

Scrivere la funzione C che riceve in ingresso due liste collegate con puntatori L1 ed L2 di valori float, e due valori float, target1 e target2 ed opera nel modo seguente:

  • Cerca gli elementi in L1 con valore uguale a target1, e gli elementi in L2 con valore uguale a target2;
  • Scollega da L1 gli elementi con valore uguale a target1 e li collega in L2 al posto degli elementi con valore uguale a L2; fa la cosa opposta per gli elementi di L2 uguali a target2.
Se il numero di elementi da scollegare e ricollegare nelle due liste sono diversi gli elementi in eccesso sono collegati in fondo alla lista. (Esempio: L1={2,3,7,2,4), target1=2, L2={7,3,4,3,3}, target2=3 → L1={3,3,7,3,4,3} e L2={7,2,4,2})

vorrei capire dove sbaglio, grazie di eventuali risposte.
il codice che ho scritto è questo:

C:
#include <stdio.h>
#include <stdlib.h>

#define TRUE 1
#define FALSE 0
typedef unsigned short int Boolean;
struct list{
    float value;
    struct list *next_ptr;
};

void init(struct list **ptrptr);
Boolean PreInsert(struct list **ptrptr,float value);
void visit(struct list *ptr);

Boolean Search(struct list *l, float target);
void CompliteList(struct list **l1,struct list **l2,float target1,float target2);
void CompliteList2(struct list **l1,struct list **l2,float target1,float target2);

int main() {
    struct list *L1;
    struct list *L2;
    float target1 = 2;
    float target2 = 3;

    init(&L1);
//inserimento dati Lista 1
    PreInsert(&L1, 4);

    PreInsert(&L1, 9);

    PreInsert(&L1, 2);

    PreInsert(&L1, 9);

    PreInsert(&L1, 2);
    //stampa elemneti prima lista
    visit(L1);

    init(&L2);
    //inserimento elementi lista 2
    PreInsert(&L2, 8);

    PreInsert(&L2, 1);

    PreInsert(&L2, 3);

    PreInsert(&L2, 5);

    PreInsert(&L2,3);
//sampa lista 2
    visit(L2);

    printf("\n");
    if (Search(L1, target1) == TRUE) {
        printf("\nil valore cercato e' presente nella lista 1\n");
    } else {
        printf("\nil valore carcato non e' presente nella lista 1\n");
    }

    if (Search(L2, target2) == TRUE) {
        printf("\nil valore  cercato e' presente nella lista 2\n");
    } else {
        printf("\nil valore cercato non e' presente nella lista 2\n");
    }
    //scambio valori
    CompliteList(&L1,&L2,target1,target2);
    CompliteList2(&L1,&L2,target1,target2);
    //sampa ellementi definitivi
    visit(L1);
    visit(L2);
}

void init(struct list **ptrptr)
{
    *ptrptr=NULL;
}
//inserimento valori
Boolean PreInsert(struct list **ptrptr,float value)
{
    struct list *tmpPtr;
    tmpPtr = (struct list *)malloc(sizeof(struct list));
    if ( tmpPtr != NULL ) {
        tmpPtr->value = value;
        tmpPtr->next_ptr = *ptrptr;
        *ptrptr = tmpPtr;
        return TRUE;
    }
    else
        return FALSE;
}


//stampa lista
void visit(struct list * ptr)
{
    printf("\nList : ");
    while ( ptr != NULL ) {
        printf("[ %f ] ", ptr->value);
        ptr = ptr->next_ptr;
    }
}

//esercizio 5
Boolean Search(struct list *l, float target)
{
    while (l!=NULL)
    {
        if(l->value==target)
            return TRUE;
        l=l->next_ptr;
    }
    return FALSE;
}


void  CompliteList(struct list **l1,struct list **l2,float target1,float target2)
{
struct list *tmp1=NULL,*tmp2=NULL;

    while (*l1!=NULL )
    {
        if((*l1)->value == target1){


            //scollega l'elemento della lista 1
            tmp1=*l1;
            *l1=(*l1)->next_ptr;

                //scollega l'elemneto della lista 2;
                tmp2 = *l2;
                *l2 = (*l2)->next_ptr;



            //collega l'elelmento della lista 1  nella lista 2
            *l2=tmp1;
            (*l2)->next_ptr = tmp2;


        } else {
            l1 = &((*l1)->next_ptr);
        }
        }
    }

void  CompliteList2(struct list **l1,struct list **l2,float target1,float target2)
{
    struct list *tmp1=NULL,*tmp2=NULL;
    while (*l2!=NULL)
    {

        if((*l2)->value == target2) {   //scollega l'elemento della lista 2
            tmp2 = *l2;
            *l2 = (*l2)->next_ptr;
            //scollega l'elemneto dell alista 1;

                tmp1 = *l1;
                *l1 = (*l1)->next_ptr;
            //collega l'elelmento nella lista 1
            *l1=tmp2;
            (*l1)->next_ptr=tmp1;
        } else
            l2 = &((*l2)->next_ptr);

    }
}
 
Ultima modifica da un moderatore:

M1n021

Nuovo Utente
143
68
Ciao, io farei qualcosa del genere:

C:
#include <stdio.h>
#include <stdlib.h>

typedef struct node_
{
    int value;
    struct node_ *next;
}   node;

void pre_insert(node **p, int value)
{
    node *new_node = (node*)malloc(sizeof(node));
    new_node->value = value;
    new_node->next = *p;
    *p = new_node;
}

void print_list(node *p, char *list_name)
{
    printf("%s:", list_name);
    while(p)
    {
        printf(" %d", p->value);
        p = p->next;
    }
    printf("\n");
}

node** search(node **p, int target)
{
    while(*p && (*p)->value != target)
    {
        p = &(*p)->next;
    }
    return p;
}

void swap(node **p_1, node **p_2)
{
    node *temp = *p_1;
    *p_1 = *p_2;
    *p_2 = temp;
}

void fun(node **p_1, int target_1, node **p_2, int target_2)
{
    while(1)
    {
        p_1 = search(p_1, target_1);
        p_2 = search(p_2, target_2);
        if(*p_1 && *p_2)
        {
            swap(p_1, p_2);
            p_1 = &(*p_1)->next;
            p_2 = &(*p_2)->next;
            swap(p_1, p_2);
        }
        else if(!*p_1 && !*p_2)
        {
            break;
        }
        else if(*p_1)
        {
            *p_2 = *p_1;
            *p_1 = (*p_1)->next;
            (*p_2)->next = NULL;
        }
        else
        {
            *p_1 = *p_2;
            *p_2 = (*p_2)->next;
            (*p_1)->next = NULL;
        }
    }
}

int main()
{
    node *L1 = NULL;
    pre_insert(&L1, 4);
    pre_insert(&L1, 2);
    pre_insert(&L1, 7);
    pre_insert(&L1, 3);
    pre_insert(&L1, 2);
    print_list(L1, "L1");

    node *L2 = NULL;
    pre_insert(&L2, 3);
    pre_insert(&L2, 3);
    pre_insert(&L2, 4);
    pre_insert(&L2, 3);
    pre_insert(&L2, 7);
    print_list(L2, "L2");

    fun(&L1, 2, &L2, 3);
    print_list(L1, "L1");
    print_list(L2, "L2");
    return 0;
}

Sembra funzionare, magari puoi trarne qualche spunto.


P.S.
Secondo voi si può fare di meglio?
 

bigendian

Utente Attivo
736
421
OS
Linux
piu che altro gli hai svolto il compito, che se lui porta al professore, facile capisca che non e' suo.

Ieri sera cercavo di capire cosa stesse sbagliando, poi sono crollato sulla tastiera tra mille task aperti, codice non e' dei peggiori, compila e non va in crash, credo dando un occhio a CompliteList, controllando bene associazione puntatori tracciando i valori, possa trovare il problema.
 
Ultima modifica:
  • Mi piace
Reazioni: BrutPitt

FraFut

Nuovo Utente
5
0
Ciao, io farei qualcosa del genere:

C:
#include <stdio.h>
#include <stdlib.h>

typedef struct node_
{
    int value;
    struct node_ *next;
}   node;

void pre_insert(node **p, int value)
{
    node *new_node = (node*)malloc(sizeof(node));
    new_node->value = value;
    new_node->next = *p;
    *p = new_node;
}

void print_list(node *p, char *list_name)
{
    printf("%s:", list_name);
    while(p)
    {
        printf(" %d", p->value);
        p = p->next;
    }
    printf("\n");
}

node** search(node **p, int target)
{
    while(*p && (*p)->value != target)
    {
        p = &(*p)->next;
    }
    return p;
}

void swap(node **p_1, node **p_2)
{
    node *temp = *p_1;
    *p_1 = *p_2;
    *p_2 = temp;
}

void fun(node **p_1, int target_1, node **p_2, int target_2)
{
    while(1)
    {
        p_1 = search(p_1, target_1);
        p_2 = search(p_2, target_2);
        if(*p_1 && *p_2)
        {
            swap(p_1, p_2);
            p_1 = &(*p_1)->next;
            p_2 = &(*p_2)->next;
            swap(p_1, p_2);
        }
        else if(!*p_1 && !*p_2)
        {
            break;
        }
        else if(*p_1)
        {
            *p_2 = *p_1;
            *p_1 = (*p_1)->next;
            (*p_2)->next = NULL;
        }
        else
        {
            *p_1 = *p_2;
            *p_2 = (*p_2)->next;
            (*p_1)->next = NULL;
        }
    }
}

int main()
{
    node *L1 = NULL;
    pre_insert(&L1, 4);
    pre_insert(&L1, 2);
    pre_insert(&L1, 7);
    pre_insert(&L1, 3);
    pre_insert(&L1, 2);
    print_list(L1, "L1");

    node *L2 = NULL;
    pre_insert(&L2, 3);
    pre_insert(&L2, 3);
    pre_insert(&L2, 4);
    pre_insert(&L2, 3);
    pre_insert(&L2, 7);
    print_list(L2, "L2");

    fun(&L1, 2, &L2, 3);
    print_list(L1, "L1");
    print_list(L2, "L2");
    return 0;
}

Sembra funzionare, magari puoi trarne qualche spunto.


P.S.
Secondo voi si può fare di meglio?
mi postesti spiegare questo pezzo di codice
Codice:
node** search(node **p, int target)
{
    while(*p && (*p)->value != target)
    {
        p = &(*p)->next;
    }
    return p;
}
 
Ultima modifica da un moderatore:

bigendian

Utente Attivo
736
421
OS
Linux
Il codice compara "value" del nodo con target, e avanza fin che ci sono nodi.

L'avanzamento pare essere errato. Prova qualcosa tipo:

Codice:
node *search(node **p, int target)
{
        while(*p && (*p)->value != target) {
                *p = (*p)->next;
        }

        return *p;
}
 

FraFut

Nuovo Utente
5
0
Il codice compara "value" del nodo con target, e avanza fin che ci sono nodi.

L'avanzamento pare essere errato. Prova qualcosa tipo:

Codice:
node *search(node **p, int target)
{
        while(*p && (*p)->value != target) {
                *p = (*p)->next;
        }

        return *p;
}
Il codice funziona vorresi sapere perché è struct e non Boolean
 

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,221
1,853
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Il codice funziona vorresi sapere perché è struct e non Boolean

Perchè ti restituisce i puntatori ai nodi che ha trovato, per poi effettuare lo scambio (se non NULL). Questo rispetta il secondo punto della richiesta:

Scollega da L1 gli elementi con valore uguale a target1 e li collega in L2 al posto degli elementi con valore uguale a L2; fa la cosa opposta per gli elementi di L2 uguali a target2.

nella tua funzione invece non effettuavi lo scambio; se la fai boolean sei costretto a fare una nuova ricerca per prendere i puntatori ai nodi e poi scambiarli.

PS: ripeto: quando posti del codice usa il tag CODE, qui viene spiegato come si fa. Grazie 😉
 
  • Mi piace
Reazioni: bigendian

bigendian

Utente Attivo
736
421
OS
Linux
per altro noto un esoso boolean "unsigned short int", e #define inutili come FALSE 0 TRUE 1 (sullo stile di #define ZERO 0), float inutili per l'esercizio,
 
  • Mi piace
Reazioni: Mario Niola
Stato
Discussione chiusa ad ulteriori risposte.

Ci sono discussioni simili a riguardo, dai un'occhiata!

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!

Discussioni Simili