Buenas Marcelo, queria preguntarte si estaban bien las funciones y tambien si habia alguna manera de ahorrarme repetir el codigo para agrandar el vector en las funciones put y putifnotpresent.
Gracias!
typedef struct keys{
elemType elem;
char flag; // 1 si hay elem, 0 si no
}keys;
/* Asocia un valor a una clave, siempre y cuando esa clave no tenga ya un
valor asociado.
No importa si el valor ya está asociado a otra clave, en ese caso igual
* asocia el valor a la clave recibida
/
void putIfNotPresent(mapADT m, size_t key, elemType elem){
if(m->size < key){
m->vec = realloc(m->vec, m->size* sizeof(struct keys));
for(int i = m->size; i < key; i++){
m->vec[i].flag = 0;
}
m->size = key;
}
// se que estoy repitiendo el codigo de agrandar pero sino no podria ver si ya hay algo en esa key
if(m->vec[key-1].flag == 0){
put(m,key,elem);
}
}
/* Asocia un valor a una clave.
Si la clave tenía otro valor asociado, lo pisa con el valor nuevo
No importa si el valor ya está asociado a otra clave, lo asocia igual a la clave * pasada
/
void put(mapADT m, size_t key, elemType elem){
if(m->size < key){
m->vec = realloc(m->vec, key* sizeof(struct keys));
for(int i = m->size; i < key; i++){
m->vec[i].flag = 0;
}
m->size = key;
}
m->vec[key-1].elem = elem;
if(m->vec[key-1].flag == 1){
return;
}
m->vec[key-1].flag = 1;
m->dim++;
}
/ Retorna un vector con todos los valores almacenados /
elemType values(const mapADT m){
elemType ans = malloc(sizeof(m->dim*sizeof(elemType)));
int j=0;
for(int i = 0; i < m->size; i++){
if(m->vec[i].flag ==1){
ans[j++]=m->vec[i].elem;
}
}
return ans;
}
/ Retorna el elemento asociado a la clave key
Si no había un elemento asociado a esa clave retorna basura y en errno
el valor ENODATA
/
elemType get(const mapADT m, size_t key){
if (key > 0 && key <= m->size){
if(m->vec[key-1].flag == 0){
errno = ENODATA;
}
return m->vec[key-1].elem;
}
return NULL; // supuse que si la key no era valida retorna NULL
}
/ Elimina una clave. Es equivalente a decir que para esa clave no hay ningún valor asociado
*/
void deleteKey(mapADT m, size_t key){
if(key > 0 && key < m->size){
if(m->vec[key-1].flag==1){
m->vec[key-1].flag=0;
m->dim--;
}
return;
}
}
Buenas Marcelo, queria preguntarte si estaban bien las funciones y tambien si habia alguna manera de ahorrarme repetir el codigo para agrandar el vector en las funciones put y putifnotpresent. Gracias!
typedef struct keys{ elemType elem; char flag; // 1 si hay elem, 0 si no }keys;
typedef struct mapCDT{ keys vec; size_t dim; // ocupados size_t size; // reservado }mapCDT; typedef mapCDT mapADT;
mapADT newMap(){ return calloc(1, sizeof(struct mapCDT)); }
void freeMap(mapADT m){ free(m->vec); free(m); }
size_t sizeMap(mapADT m){ return m->dim; }
void put(mapADT m, size_t key, elemType elem);
/* Asocia un valor a una clave, siempre y cuando esa clave no tenga ya un valor asociado. No importa si el valor ya está asociado a otra clave, en ese caso igual * asocia el valor a la clave recibida / void putIfNotPresent(mapADT m, size_t key, elemType elem){ if(m->size < key){ m->vec = realloc(m->vec, m->size* sizeof(struct keys)); for(int i = m->size; i < key; i++){ m->vec[i].flag = 0; } m->size = key; } // se que estoy repitiendo el codigo de agrandar pero sino no podria ver si ya hay algo en esa key if(m->vec[key-1].flag == 0){ put(m,key,elem); } }
/* Asocia un valor a una clave. Si la clave tenía otro valor asociado, lo pisa con el valor nuevo No importa si el valor ya está asociado a otra clave, lo asocia igual a la clave * pasada / void put(mapADT m, size_t key, elemType elem){ if(m->size < key){ m->vec = realloc(m->vec, key* sizeof(struct keys)); for(int i = m->size; i < key; i++){ m->vec[i].flag = 0; } m->size = key; } m->vec[key-1].elem = elem; if(m->vec[key-1].flag == 1){ return; } m->vec[key-1].flag = 1; m->dim++; }
/ Retorna un vector con todos los valores almacenados / elemType values(const mapADT m){ elemType ans = malloc(sizeof(m->dim*sizeof(elemType))); int j=0; for(int i = 0; i < m->size; i++){ if(m->vec[i].flag ==1){ ans[j++]=m->vec[i].elem; } } return ans; }
/ Retorna el elemento asociado a la clave key Si no había un elemento asociado a esa clave retorna basura y en errno el valor ENODATA / elemType get(const mapADT m, size_t key){ if (key > 0 && key <= m->size){ if(m->vec[key-1].flag == 0){ errno = ENODATA; } return m->vec[key-1].elem; } return NULL; // supuse que si la key no era valida retorna NULL }
/ Elimina una clave. Es equivalente a decir que para esa clave no hay ningún valor asociado */ void deleteKey(mapADT m, size_t key){ if(key > 0 && key < m->size){ if(m->vec[key-1].flag==1){ m->vec[key-1].flag=0; m->dim--; } return; } }