Open romamati opened 1 year ago
No puedo correrlo con nuestro testeo, hay algunas diferencias, por ejemplo el tipo que devuelve deleteElement. Subí el .h y el man que usaste para probarlo.
Ahh oka! DeleteElement tiene que ser void (ahi lo modifique).
El .h seria este:
typedef struct setCDT setADT; //Siempre tengo que aclarar que es struct aca!!! typedef char elemType; typedef int (*compare)(elemType e1, elemType e2);//Puntero a funcion que compara elementos genericos
//Crea un nuevo stack setADT newSet(compare cmp);
//Adhiere un elemento al set y retorna 1 si lo pudo meter o cero sino int addElement(setADT set, elemType e);
//Se fija si el elemento pertenece al set int setContains(setADT set, elemType e);
//Crea un set de rta con la union de los dos sets que recibe como parametro setADT unionSet(setADT s1, setADT s2);
//Libera toda la memoria del set void freeSet(setADT set);
//crea un set de rta con la interseccion de s1 y s2 y lo retorna setADT intersectionSet(setADT s1, setADT s2);
//Crea un set de rta con todos los elementos de s1 que no estan en s2 setADT diffSet(setADT s1, setADT s2);
//Elimina un elemento del set y retorna la direccion del set modificado. Si no lo puede eliminar pues no esta retorna NULL setADT deleteElement(setADT s, elemType e);
//Indica si el set que recibe por parametro posee o no posee elementos(si esta vacio retorna 1 y sino 0) int isEmptySet(setADT s1);
//Indica la cantidad de elementos que posee el set size_t sizeSet(setADT s);
Y el Test que estoy corriendo seria este:
//Defino esta funcion porque sino no me toma al strcmp como tipo de funcion a la que apunte compare. int strcmp1(elemType t, elemType s) { int i = 0; while( (t[i] && s[i]) && t[i] - s[i] == 0 ) { i++; } //si saliste porque ambos llegaron a su final entonces son iguales y retorna cero //si saliste porque t llego a su fin pero s no entonces retorna negativo //sino es porque s llego a su fin y t no y por ende retorna positivo
return t[i]-s[i];
}
/ Utilizamos char como elemType y strcmp como compare */ int main(void) { setADT set1 = newSet(strcmp1); setADT set2 = newSet(strcmp1); setADT ans; int ok; ok = addElement( set1, "amelia" ); assert( ok && setContains( set1, "amelia" ) ); ok = addElement( set1, "amelia" ); assert( ok == 0 ); addElement( set1, "belen" ); addElement( set1, "carlos" ); // set1 = {"amelia", "belen", "carlos"} addElement( set2, "carlos" ); addElement( set2, "daniel" ); addElement( set2, "emilia" ); // set2 = {"carlos", "daniel", "emilia"}
ans = unionSet( set1, set2 );
assert( setContains(ans, "amelia") && setContains(ans, "daniel"));
freeSet(ans);
ans = intersectionSet( set1, set2 );
assert( setContains(ans, "carlos") && setContains(ans, "amelia") == 0 );
freeSet(ans);
ans = diffSet( set1, set2 );
assert( setContains(ans, "amelia") && setContains(ans, "carlos") == 0 );
freeSet(ans);
deleteElement( set1, "carlos" );
ans = intersectionSet(set1, set2);
assert( isEmptySet(ans) );
freeSet(set1);
freeSet(set2);
freeSet(ans);
// test con conjuntos de un elemento
set1 = newSet(strcmp1);
set2 = newSet(strcmp1);
ok = addElement( set1, "amelia" );
ok = addElement( set2, "amelia" );
ans = intersectionSet( set1, set2 );
assert( setContains(ans, "amelia") == 1 );
assert(sizeSet(ans)==1);
freeSet(ans);
ans = unionSet( set1, set2 );
assert( setContains(ans, "amelia") == 1 );
assert(sizeSet(ans)==1);
freeSet(ans);
// Diferencia de un conjunto con un solo elemento
freeSet(set2);
set2 = newSet(strcmp1);
ans = diffSet( set1, set2 );
assert(sizeSet(ans)==1);
freeSet(ans);
freeSet(set1);
freeSet(set2);
puts("OK!");
}
El problema está en el delete, en realidad hay dos problemas
1) Acá hay que usar la función de comparación. if(l->e == e)//Entonces elimino
2) Está mal la llamada, si borrás el tercero perdés también los dos anteriores
l = deleteElementRec(l->tail, e, flag);
al igual que en el add debe ser
l->tail = deleteElementRec(l->tail, e, flag);
por eso los leaks, porque perdías referencia a los anteriores y nunca se liberaban
Ahh perfecto! Muchas gracias.
//Me indica que en la funcion addRec me quedan memory leaks y no entiendo donde me faltaria hacer un free.
include
include
include "ej8ADT.h"
typedef struct node { elemType e; struct node * tail; }Tnode;
typedef Tnode * TList;//Puntero a struct
typedef struct setCDT { compare cmp; size_t size;//Cantidad de nodos de la lista TList first;//Puntero al primer nodo de la lista }setCDT;
//Crea un nuevo stack setADT newSet(compare cmp) { setADT set = calloc(1, sizeof(*set)); set->cmp = cmp; return set; }
static TList addRec(TList l, elemType e, int flag, compare cmp) { int c; if(l == NULL || (c = cmp(l->e, e)) > 0) //En cualquiera de estos casos tengo que adherir al elemento { TList aux = malloc(sizeof(aux)); aux->e = e; aux->tail = l;//Pues lo estoy metiendo antes del elemento actual de la lista *flag = 1;//Indico que pude meter al elemento return aux; //Retorno a la direccion de la lista con las modificaciones a donde la llamen }
}
//Adhiere un elemento al set y retorna 1 si lo pudo meter o cero sino int addElement(setADT set, elemType e) { int flag = 0; set->first = addRec(set->first, e, &flag, set->cmp); set->size+=flag; return flag; }
static int ContainsRec(TList l, elemType e, compare cmp) { int c; if(l == NULL || (c= cmp(l->e, e))>0) //En cualquiera de estos casos ya sabemos que el elemento no esta { return 0; }
}
//Se fija si el elemento pertenece al set int setContains(setADT set, elemType e) { return ContainsRec(set->first, e, set->cmp); }
static TList unionRec(TList l1, TList l2, size_t * size) { if(l1 == NULL && l2 == NULL) { return NULL; }
}
//Crea un set de rta con la union de los dos sets que recibe como parametro setADT unionSet(setADT s1, setADT s2) { setADT rta = newSet(s1->cmp); size_t size = 0; rta->first = unionRec(s1->first, s2->first, &size); rta->size = size; return rta; }
static void freeSetRec(TList l) { if(l == NULL) { return; }
} //Libera toda la memoria del set void freeSet(setADT set) { freeSetRec(set->first); free(set);//Libero al set en si return; }
static TList intersectRec(TList l1, TList l2, size_t * size) { if(l1 == NULL || l2 == NULL)//Si alguna de las listas es vacia no hay nada que hacer pues no hay nada en la interseccion { return NULL; }
}
//crea un set de rta con la interseccion de s1 y s2 y lo retorna setADT intersectionSet(setADT s1, setADT s2) { setADT rta = newSet(s1->cmp); size_t size = 0; rta->first = intersectRec(s1->first, s2->first, &size); rta->size = size; //Asigno el tamaño de la rta return rta; }
static TList diffRec(TList l1, TList l2, size_t * size) { if(l1 == NULL) { return NULL; }
}
//Crea un set de rta con todos los elementos de s1 que no estan en s2 setADT diffSet(setADT s1, setADT s2) { setADT rta = newSet(s1->cmp); size_t size = 0; rta->first = diffRec(s1->first, s2->first, &size); rta->size = size; return rta; }
static TList deleteElementRec(TList l, elemType e, int *flag) { if(l == NULL)//Si la lisat es vacia no hay nada que eliminar y retorna NULL { return NULL; }
}
//Elimina un elemento del set y retorna la direccion del set modificado. Si no lo puede eliminar pues no esta retorna NULL setADT deleteElement(setADT s, elemType e) { int flag = 0; s->first = deleteElementRec(s->first, e, &flag); s->size-=flag;//Si lo elimino disinuyo el size en 1 return s; }
//Indica si el set que recibe por parametro posee o no posee elementos(si esta vacio retorna 1 y sino 0) int isEmptySet(setADT s1) { return s1->first == NULL; }
//Indica la cantidad de elementos que posee el set size_t sizeSet(setADT s) { return s->size; }