Advertisement
diofanto33

23-02-dict.c

Jun 22nd, 2023
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.41 KB | None | 0 0
  1. #include <stdlib.h>     /* malloc(), free()... */
  2. #include <stdbool.h>    /* bool type           */
  3. #include <assert.h>     /* assert()            */
  4. #include "key_value.h"  /* key_t               */
  5. #include "dict.h"       /* intarface           */
  6.  
  7. struct _s_dict {
  8.   unsigned int size;
  9.   struct _node_t * first;
  10. };
  11.  
  12. // Internal structure
  13. struct _node_t {
  14.   key_t key;
  15.   value_t value;
  16.   struct _node_t *next;
  17. };
  18.  
  19. struct _node_t
  20. *create_node(key_t k, value_t v)
  21. {
  22.   struct _node_t *new_node=malloc(sizeof(struct _node_t));
  23.   new_node->key=k;
  24.   new_node->value=v;
  25.   new_node->next=NULL;
  26.  
  27.   return(new_node);
  28. }
  29.  
  30. struct _node_t
  31. *destroy_node(struct _node_t *node)
  32. {
  33.   node->key = key_destroy(node->key);
  34.   node->value = value_destroy(node->value);
  35.   free(node);
  36.   node=NULL;
  37.  
  38.   return(node);
  39. }
  40.  
  41. /*
  42.  * @brief: decrease the value of size in 1.
  43.  * * @param: dict, instance of dict_t.
  44.  * @return: void.
  45.  * @pre: dict != NULL.
  46.  * @post: dict->size = dict->size - 1.
  47.  * @invariant dict->size >= 0.
  48.  */
  49.  
  50. static void
  51. decrease_size(dict_t dict)
  52. {
  53.   dict->size = dict->size - 1u;
  54. }
  55.  
  56. /*
  57.  * @brief: increase the value of size in 1.
  58.  * @param: dict, instance of dict_t.
  59.  * @return: void.
  60.  * @pre: dict != NULL.
  61.  * @post: dict->size = dict->size + 1.
  62.  * @invariant dict->size >= 0.
  63.  */
  64.  
  65. static void
  66. increase_size(dict_t dict)
  67. {
  68.   dict->size = dict->size + 1u;
  69. }
  70.  
  71. /*
  72.  * @brief: para toda instancia de dict_t se ve cumplir
  73.  *
  74.  *  1) Existencia (inicializacion).
  75.  *  2) Consistencia de la cantidad de nodos en ralacion con size.
  76.  *  
  77.  * @param: dict, instancia de dict_t.
  78.  * @return: true si se cumple la invariante, false en caso contrario.
  79.  */
  80.  
  81. static bool
  82. invrep(dict_t dict)
  83. {  
  84.   bool res = (dict != NULL);
  85.   if(res)
  86.   {  
  87.     unsigned int length = 0u;
  88.     struct _node_t *sp = dict->first;
  89.     while(sp != NULL)
  90.     {
  91.       length = length + 1u;
  92.       sp = sp->next;
  93.     }
  94.     res = res && (length==dict->size);
  95.   }
  96.    
  97.   return(res);
  98. }
  99. // --- Interface functions ---
  100.  
  101. dict_t
  102. dict_empty(void)
  103. {
  104.   struct _s_dict *dict = NULL;
  105.   dict = malloc(sizeof(struct _s_dict));
  106.   assert(dict != NULL);
  107.   dict->first = NULL;
  108.   dict->size = 0u;
  109.   assert(invrep(dict));
  110.  
  111.   return(dict);
  112. }
  113.  
  114. dict_t
  115. dict_add(dict_t dict, key_t word, value_t def)
  116. {
  117.   assert(invrep(dict));
  118.   struct _node_t *new_node = create_node(word, def);
  119.   if(dict->size==0u)
  120.   {
  121.     dict->first = new_node;
  122.     increase_size(dict);
  123.   }
  124.   else
  125.   {
  126.     struct _node_t *sp = dict->first;
  127.     struct _node_t *prev = NULL;
  128.     while(sp->next != NULL && !string_eq(word, sp->key))
  129.     {
  130.       prev = sp;
  131.       sp = sp->next;
  132.     }
  133.     if(string_eq(word, sp->key))
  134.     {
  135.       if(prev != NULL)
  136.       {
  137.         prev->next = new_node;
  138.       }
  139.       else
  140.       {
  141.         dict->first = new_node;
  142.       }
  143.       new_node->next = sp->next;
  144.       sp = destroy_node(sp);
  145.     }
  146.     else
  147.     {
  148.       sp->next = new_node;
  149.       increase_size(dict);
  150.     }
  151.     sp = NULL;
  152.   }
  153.   assert(invrep(dict));
  154.  
  155.   return(dict);
  156. }
  157.  
  158. value_t
  159. dict_search(dict_t dict, key_t word)
  160. {
  161.   assert(invrep(dict));
  162.   value_t def = NULL;
  163.   if(dict_length(dict)!=0u)
  164.   {
  165.     struct _node_t *sp = dict->first;
  166.     bool stop = false;
  167.     while(sp != NULL && !stop)
  168.     {
  169.       if(string_eq(sp->key, word))
  170.       {
  171.         def = sp->value;
  172.         stop = true;
  173.       }
  174.       sp = sp->next;
  175.     }
  176.     sp = NULL;
  177.   }
  178.   assert(invrep(dict) && (def != NULL)==dict_exists(dict, word));
  179.  
  180.   return(def);
  181. }
  182.  
  183. bool
  184. dict_exists(dict_t dict, key_t word)
  185. {
  186.   assert(invrep(dict));
  187.   bool exists = false;
  188.   if(dict_length(dict) != 0u)
  189.   {
  190.     struct _node_t *sp = dict->first;
  191.     while(sp != NULL && !exists)
  192.     {
  193.       if(string_eq(sp->key, word))
  194.       {
  195.         exists = true;
  196.       }
  197.       sp = sp->next;
  198.     }
  199.     sp = NULL;
  200.   }
  201.   assert(invrep(dict));
  202.  
  203.   return(exists);
  204. }
  205.  
  206. unsigned int
  207. dict_length(dict_t dict)
  208. {
  209.   return(dict->size);
  210. }
  211.  
  212. dict_t
  213. dict_remove(dict_t dict, key_t word)
  214. {
  215.   assert(invrep(dict));
  216.   if(dict_length(dict)!=0u)
  217.   {
  218.     struct _node_t *sp = dict->first;
  219.     struct _node_t *prev = NULL;
  220.     while(sp->next != NULL && !string_eq(sp->key, word))
  221.     {
  222.       prev = sp;
  223.       sp = sp->next;
  224.     }
  225.     if(string_eq(sp->key, word))
  226.     {
  227.       if(prev != NULL)
  228.       {
  229.         prev->next = sp->next;
  230.       }
  231.       else
  232.       {
  233.         dict->first = sp->next;
  234.       }
  235.       sp = destroy_node(sp);
  236.       dict->size = dict->size -1u;
  237.     }
  238.     sp = NULL;
  239.   }
  240.   assert(invrep(dict));
  241.  
  242.   return(dict);
  243. }
  244.  
  245. void
  246. dict_dump(dict_t dict, FILE *file)
  247. {
  248.   assert(invrep(dict));
  249.   for(struct _node_t *check=dict->first; check!=NULL; check=check->next)
  250.   {
  251.     fprintf(file, "key: ");
  252.     key_dump(check->key, file);
  253.     fprintf(file, "\n");
  254.     fprintf(file, "value: ");
  255.     value_dump(check->value, file);
  256.     fprintf(file, "\n\n");
  257.   }
  258. }
  259.  
  260. dict_t
  261. dict_remove_all(dict_t dict)
  262. {
  263.   assert(invrep(dict));
  264.   struct _node_t *sp = dict->first;
  265.   while(sp != NULL)
  266.   {
  267.     dict->first = dict->first->next;
  268.     sp = destroy_node(sp);
  269.     sp = dict->first;
  270.     decrease_size(dict);  
  271.   }
  272.   assert(invrep(dict) && dict_length(dict)==0u && dict->first==NULL);
  273.  
  274.   return(dict);
  275. }
  276.  
  277. dict_t dict_destroy(dict_t dict) {
  278.     assert(invrep(dict));
  279.     dict = dict_remove_all(dict);
  280.     free(dict);
  281.     dict=NULL;
  282.     assert(dict==NULL);
  283.  
  284.     return(dict);
  285. }
  286.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement