PDA

View Full Version : [ C ] Problema liste


.Zero
04-09-2015, 16:37
Salve a tutti! :)

In questi giorni sto affrontando lo studio delle liste nel linguaggio C e un piccolo problema è affiorato durante lo svolgimento di qualche esercizio.

Sostanzialmente, il mio problema lo riscontro nel main: non riesco a inizializzare n stringhe in una lista.

Qualcuno può aiutarmi a capire come risolvere questo problema? Io proprio non riesco a venire a capo. :help:

.Zero
04-09-2015, 19:03
scusami, ma ho la palla di vetro dal meccanico. :mbe:

Se magari dai qualche dettaglio del problema o fai vedere il codice magari qualcuno ti rispondera' anche...

Si, scusami! Questa è la traccia:

Si vuole una funzione che elimina tutti i nodi di una lista contenenti una data chiave. Quella di input è una lista concatenata.
La chiave contenuta in ogni nodo è una stringa, quindi il prototipo dei nodi sarà:

struct nodo {
char *chiave;
struct nodo *prec;
struct nodo *succ;
};

Questo è il prototipo della funzione:

struct nodo *DividiLista (nodo *a, char *k);

dove a è la lista da cui bisogna eliminare tutti i nodi che contengono, nel campo chiave, una stringa uguale a k.

Per quanto riguarda il codice, l'ho fatto e non dovrebbero esserci errori sintattici, ma non riuscendo a costruire il main ( per il problema sopra esposto ) non capisco se è funzionante o meno.
Se comunque potrebbe servire lo inserisco. :)

.Zero
04-09-2015, 21:43
si, posta anche il main()...

Il main non l'ho fatto ( non riesco a impostarlo ). Per codice intendevo le funzioni che mi servono per risolvere il problema. Comunque, questo è quello che ho scritto:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct nodo {

char *chiave;
struct nodo *prec;
struct nodo *succ;

};
typedef struct nodo nodo;




nodo *DividiLista ( nodo *a, char *k ) {

nodo *p;
int f;
p = a;

f = strcmp ( p->chiave, k );


while ( p != NULL ) {

if (( f < 0 ) || ( f > 0 )){
p = p->succ;

}

if ( (f == 0) && (p->succ = NULL) ) {

p = p->prec;
free ( p->succ->chiave );
free ( p->succ );

}

if (( f == 0 )&& ( a = p )) {

a = a->succ;
p = p->succ;
free (p->prec->chiave);
free ( p->prec );

}

if (( f == 0 ) && ( p != a)) {


free ( p->chiave );
free ( p );
p->prec->succ = p->succ;
p->succ->prec = p->prec;
p = p->succ;

}

p = p->succ;

}

return a;

}

.Zero
05-09-2015, 09:43
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

struct nodo
{
char *chiave;
struct nodo *prec, *succ;

};
typedef struct nodo nodo;

nodo *DividiLista(nodo*, char*);
nodo *CancellaZero(nodo*);
nodo *CancellaUno(nodo*);



nodo *DividiLista( nodo *a, char *k )
{
nodo *p;

while ( a != NULL && strcmp(a->chiave, k) == 0 ){
a = CancellaZero( a );

}

if ( a == NULL )
{
return NULL;

}


p = a;

while( p->succ != NULL )
{
if ( strcmp(p->succ->chiave, k) == 0 ){
p = CancellaUno( p );

} else {

p = p->succ;

}
}

return a;
}


nodo *CancellaZero( nodo *a )
{
nodo *p;
if ( a == NULL )
return NULL;

p = a->succ;

if( p != NULL)
p->prec = NULL;

free(a->chiave);
free(a);
return p;
}


nodo *CancellaUno( nodo *a)
{
nodo *p;

if( a->succ == NULL )
return a;

p = a->succ;
a->succ = p->succ;

if(p->succ != NULL)
p->succ->prec = a;
free(p->chiave);
free(p);
return a;
}

.Zero
05-09-2015, 17:34
codice tra tag "code" e reindentazione... la prima volta l'ho fatto io, ora fallo tu cosi' e' piu' leggibile :)

Sistemato, e spero che ora sia più leggibile. :)

.Zero
06-09-2015, 21:22
Mmh... ho capito.
E ora come faccio a costruire la funzione main per far partire il programma?

.Zero
07-09-2015, 16:40
Tenendo presente quello che hai scritto ho progettato il main nel modo seguente:


int main () {

char *s[5] = {"cane", "gatto", "camaleonte", "leone", "scimmia"};
char *c = {"gatto"};
char *l = {"leone"};


nodo *a = NULL;
int i;

for ( i = 0; i<=5; i++ ) {

a = InserisciLista ( a, s[i], 0 );

}

a = DividiLista( a, c, l );

MostraLista(a);

}


Dove "InserisciLista" è definita come segue:

nodo *InserisciLista( nodo *a, char *chiave, int i ){
nodo *p, *q;
if( i == 0){
p = malloc(sizeof(nodo));
p->chiave = chiave;
p->prec = NULL;
p->succ = a;
if( a != NULL)
a->prec = p;
a = p;
} else {
p = malloc(sizeof(nodo));
p->chiave = chiave;
p->prec = a;
p->prec->succ = p;
a = p;
}
return a;
}


"DividiLista" è la funzione che ho già presentato in qualche messaggio precedente. Infine, "MostraLista" non fa altro che mostrare a video il risultato. Purtroppo quando vado a compilare il tutto mi dà errore.

.Zero
12-09-2015, 08:29
inserisci lista mi sembra inutilmente complicata, se vuoi semplicemente inserire in coda


void insertLista(list *p, char *string)
{
// this assumes that p exists, i.e. not NULL
if (!p)
return;

while (p->next)
{
p = p->next;
}

p->next = (list *) malloc(sizeof(list));
strcpy( p->next->key, string );
p->next->prev = p;
p->next->next = NULL;

}


non capisco quell'intero i a che serva nella tua funzione...

Eccomi!
Perdona l'attesa ma sono stato senza internet in questi giorni.

"i" mi permette di far partire la funzione, fondamentalmente, perché nel main lo imposto come 0 ( zero ) e, quindi, mi fa partire la funzione. Un controllo inutile, pensi?

.Zero
14-09-2015, 20:10
si, ora ho capito. secondo me e' inutilmente complicato.

Si, è solo per permettere alla funzione di partire. :)
Ho risolto il problema, comunque. Ho utilizzato la funzione "InserisciZero" e ho inserito manualmente le varie parole, senza utilizzare altre funzioni:


nodo *InserisciZero(nodo *a, char *k){
nodo *p;
p = malloc(sizeof(nodo));
p->chiave = k;
if( a == NULL){
p->succ = NULL;
p->prec = NULL;
return p;
}
p->succ = a;
p->prec = NULL;
a->prec = p;
return p;
}


E nel main ho semplicemente utilizzato la suddetta funzione più volte, così da riempire la lista a mio piacimento:


main(){
nodo *a= NULL;

a = InserisciZero(a, "bue");
a = InserisciZero(a, "capra");
a = InserisciZero(a, "serpente");
a = InserisciZero(a, "maiale");
a = InserisciZero(a, "topo");

char *k = "capra";
char *k1 = "maiale";

printf("Lista originale:\n");
MostraLista(a);

a = EstraiSegmento(a, k, k1);

printf("Lista modificata:\n");
MostraLista(a);
}


Grazie per i chiarimenti, gli aiuti e il tempo messo a disposizione. :)