PDA

Visualizza la versione completa : [C] Esercizio sulle LISTE


davidex21
27-02-2013, 01:21
Ciao a tutti,
ho il seguente testo:

"data la seguente definizione di tipo:

typedef struct nd{
int val;
struct nd *next;
}TND;

a) definisce 4 liste: lInt, lPositivi, lNegativi e lABS di tipo TND;
b) inserisce nella lInt i numeri interi contenuti in un file denominato "dati.txt";
c) attraverso una funzione, inserisce nelle liste lPositivi e lNegativi rispettivamente i numeri positivi e negativi contenuti in lInt;
d) attraverso una funzione, inserisce nella lista lABS il valore assoluto di tutti i numeri contenuti in lPositivi e lNegativi senza duplicati."

i punti a e b riesco a farli senza problemi, ma i punti c e d no. In particolare non riesco a creare un unica funzione che permetta di inserire i numeri, contenuti in lInt, in lPositivi se >=0, in lNegativi se <0. Il prototipo della funzione potrebbe essere: void dividi(lInt, lPositivi, lNegativi).

Qualcuno può aiutarmi?
Grazie mille

torn24
27-02-2013, 10:56
Ciao , le quattro liste sono tutte uguali , quindi ti crei una funzione per inserire dati nella lista , che userei per tutte e 4 le liste .

Le condizioni necessarie le sai , quindi bastano un if else












void dividi(TND lInt,TND lPositivi, TND lNegativi)
{

TND *temp=lInt;

while(temp!=NULL)
{
if(temp->val >=0)
funzione_inserimento(lpositivi, val);
else
funzione_inserimento(lNegativi,val);


temp=temp->next;

}


}





MA TI CONSIGLIO di aspettare persone più esperte , sinceramente non vedo il problema per il punto c :)

Marco1995
27-02-2013, 18:15
i punti a e b riesco a farli senza problemi, ma i punti c e d no. In particolare non riesco a creare un unica funzione che permetta di inserire i numeri, contenuti in lInt, in lPositivi se >=0, in lNegativi se <0. Il prototipo della funzione potrebbe essere: void dividi(lInt, lPositivi, lNegativi).

Qualcuno può aiutarmi?
Grazie mille

Ciao...per il punto c io farei così:


void Spartizione(TND* listaoriginale,TND* &pos,TND* &neg,int numpos,int numneg);

Dove numpos e numneg sono il numero di valorì positivi e negativi che ci sono all'interno della lista originale.In questo modo sai esattamente quanto spazio allocare.
Per il punto d farei una funzione del tipo


TND* valassoluto(TND* listaoriginale);

Prende in input la lista originale...sarebbe equivalente a prendere le due liste lPos e lNeg e restituisce una lista.

Ovviamente ti ho implementato solo i prototipi...ma da questi alla risoluzione dell'esercizio il passo è breve ;)

davidex21
27-02-2013, 19:11
Vi ringrazio molto, adesso proverò a seguire i vostri consigli :)

per il punto d) anch'io avevo pensato ad una funzione come da te indicato "TND* valassoluto(TND* listaoriginale);" ma il professore ha contestato il fatto di aver preso i numeri dalla lista originale perchè lui chiedeva che venissero presi da lPositivi e lNegativi.

Grazie mille ancora

Marco1995
27-02-2013, 19:25
ma il professore ha contestato il fatto di aver preso i numeri dalla lista originale perchè lui chiedeva che venissero presi da lPositivi e lNegativi.

Bè se la traccia è così va rispettata...ma a livello logico non ha senso :D

davidex21
28-02-2013, 01:05
Eh lo so che a livello logico non ha senso, purtroppo anche il prof non ha senso logico :D

Questo è il programma che ho fatto, ma mi da lista vuota sia per lPositivi che per lNegativi:


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

typedef struct nd{
int val;
struct nd *next;
}TLISTA;

TLISTA *newLista();
TLISTA *addLista(TLISTA *lista, int num);
void printLista(TLISTA *lista);
void dividi(TLISTA *lista, TLISTA *lPositivi, TLISTA *lNegativi);

int main()
{
TLISTA *lInt;
TLISTA *lPositivi;
TLISTA *lNegativi;
FILE *fp;
int num;
lInt=newLista();
lPositivi=newLista();
lNegativi=newLista();
fp=fopen("dati.txt", "r");
while(fscanf(fp, "%d", &num)!=EOF){
lInt=addLista(lInt, num);
}
fclose(fp);
printf("\n Lista 'lInt':\n\n");
printLista(lInt);
printf("\n\n Lista 'lPositivi':\n\n");
dividi(lInt, lPositivi, lNegativi);
printLista(lPositivi);
printf("\n\n Lista 'lNegativi':\n\n");
printLista(lNegativi);
printf("\n\n");
system("PAUSE");
return 0;
}

TLISTA *newLista(){
return NULL;
}

TLISTA *addLista(TLISTA *lista, int num){
TLISTA *t;
TLISTA *i;
t=(TLISTA *)malloc(sizeof(TLISTA));
if(t==NULL){
printf("Errore di memoria!\n");
exit(-1);
}
else{
t->val=num;
t->next=NULL;
}
i=lista;
if(lista==NULL){
return t;
}
else{
while(i->next!=NULL){
i=i->next;
}
i->next=t;
return lista;
}
}

void printLista(TLISTA *lista){
if(lista==NULL){
printf("lista vuota!\n");
}
else{
while(lista!=NULL){
printf("%4d", lista->val);
lista=lista->next;
}
}
}

void dividi(TLISTA *lista, TLISTA *lPositivi, TLISTA *lNegativi){
TLISTA *temp;
temp=lista;
while(temp!=NULL){
if(temp->val>=0){
lPositivi=addLista(lPositivi, temp->val);
}
else{
lNegativi=addLista(lNegativi, temp->val);
}
temp=temp->next;
}
}


sapreste dirmi dove può essere l'errore?

torn24
28-02-2013, 10:27
ciao , devo dirti che il codice andrebbe messo tra tag code , e che qualche moderatore te lo farà notare :)

per il problema , sembra che tutto sia corretto , e che tutte le funzioni facciano il loro lavoro ,
solo ,all'uscita della funzione dividi (),i puntatori lPositivi lNegativi sono nulli , ma non sembra esserci errori nella funzione io ho provato con qualche printf e tutto funziona

COME ho testato la funzione dividi() che sembra funzionare



void dividi(TLISTA *lista, TLISTA *lPositivi, TLISTA *lNegativi){
TLISTA *temp;
temp=lista;
while(temp!=NULL){
if(temp->val>=0){
lPositivi=addLista(lPositivi, temp->val);
if(lPositivi==NULL)puts("non restituito puntatore");//lPositivi non è nullo
printf("valore %d \n" ,temp->val);
}
else{
lNegativi=addLista(lNegativi, temp->val);
printf("valore negativi %d \n" ,temp->val);
}
temp=temp->next;
}

while(lPositivi!=NULL) // i dati vengono stampati correttamente
{
printf(" positivi funzione %d\n",lPositivi->val);
lPositivi=lPositivi->next;
}
while(lNegativi!=NULL)
{
printf(" negativi funzione %d\n",lNegativi->val);
lNegativi= lNegativi->next;
}
}







Quindi non so proprio perche non funziona ????

Marco1995
28-02-2013, 15:19
sapreste dirmi dove può essere l'errore?

Innanzitutto come ti è stato già suggerito è opportuno utilizzare gli appositi tag per il codice,così da rendere molto più leggibile il codice ad altri.
L'errore sta nella funzione dividi...o meglio..nel prototipo della funzione dividi.
Dato che il contenuto delle liste deve essere modificato e reso all'esterno modificato occorre passare le liste by reference..in particolare:


void dividi(TLISTA *lista, TLISTA *&lPositivi, TLISTA *&lNegativi)

Così facendo dai la possibilità alla funzuione di modificare permanentemente il valore della lista.
Senza la & la funzione modificherebbe il valore della lista all'interno della funzione ma non all'esterno!!..questo spiega perchè torn24 non rileva errori dentro alla funzione..

:ciauz:

davidex21
16-03-2013, 18:24
Ciao, innanzitutto vi ringrazio per i consigli. Ho preso spunto dal codice di turn24 ed ho riscritto così la funzione dividi:


void dividi(TLISTA *lista, TLISTA *lPos, TLISTA *lNeg){
TLISTA *temp;
temp=lista;
while(temp!=NULL){
if(temp->val>=0){
lPos=addLista(lPos, temp->val);
if(lPos==NULL){
puts("Puntatore non restituito!");
}
}
else{
lNeg=addLista(lNeg, temp->val);
}
temp=temp->next;
}
printf("\n\n Lista 'lPos':\n\n");
printLista(lPos);
printf("\n\n Lista 'lNeg':\n\n");
printLista(lNeg);
}

praticamente identica con qualche accorgimento "estetico" javascript:void(0);
la funzione funziona perfettamente.

Ho creato la funzione insABS per inserire nella lista lABS il valore assoluto di tutti i numeri presenti nella lista iniziale lInt:


TLISTA *insABS(TLISTA *lista){
TLISTA *temp;
TLISTA *j;
j=NULL;
temp=lista;
while(temp!=NULL){
if(temp->val<0){
temp->val=-(temp->val);
}
else{
temp->val=temp->val;
}
j=addLista(j, temp->val);
temp=temp->next;
}
return j;
}

funzione corretta ma vorrei eliminare i duplicati e non so come fare. Qualcuno saprebbe consigliarmi?

Grazie mille

Marco1995
16-03-2013, 19:15
Potresti crearti una funzione che scandisce l'intera lista...poi se trova un elemento uguale ritorna l'indice dell'elemento uguale all'altro.Dopodichè tramite un'altra funzione che riceve come parametro il numero progressivo del nodo lo elimina.

Per spiegarmi,una cosa del tipo:



//Funzione ottieni indice
int indice = 0;
supporto = lista->next;
while(lista->next!=NULL)
{
while(supporto!=NULL)
{
if (lista->val == supporto->val)
return indice;
indice++;
supporto = supporto->next;
}
lista = lista->next;
}
return -1; //Se non trova nessun valore uguale ritorna -1 che annuncia un esito negativo
}

//funzione elimina nodo
void eliminanodo(Tlista* &lista,int indice)
{
//scorri la lista fino a quando non arrivi al nodo giusto e poi lo elimini
}

Loading