learning-cc4e

Solution to https://cc4e.com/. If you copy these you're not right in the head.
git clone https://kaka.farm/~git/learning-cc4e
Log | Files | Refs

main.c (3403B)


      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 
      5 struct HashMapEntry {
      6     char *key;  /* public */
      7     int value;  /* public */
      8     struct HashMapEntry *__prev;
      9     struct HashMapEntry *__next;
     10 };
     11 
     12 struct HashMapIter {
     13     int __bucket;
     14     struct HashMap *__map;
     15     struct HashMapEntry *__current;
     16 
     17     struct HashMapEntry* (*next)(struct HashMapIter* self);
     18     void (*del)(struct HashMapIter* self);
     19 };
     20 
     21 struct HashMap {
     22     /* Attributes */
     23     int __buckets;
     24     struct HashMapEntry *__heads[8];
     25     struct HashMapEntry *__tails[8];
     26     int __count;
     27 
     28     /* Methods */
     29     void (*put)(struct HashMap* self, char *key, int value);
     30     int (*get)(struct HashMap* self, char *key, int def);
     31     int (*size)(struct HashMap* self);
     32     void (*dump)(struct HashMap* self);
     33     struct HashMapIter* (*iter)(struct HashMap* self);
     34     void (*del)(struct HashMap* self);
     35 };
     36 
     37 void __HashMap_del(struct HashMap* self)
     38 {
     39     int i;
     40     struct HashMapEntry *cur, *next;
     41 
     42     for(i=0; i<self->__buckets; i++) {
     43         cur = self->__heads[i];
     44         while(cur) {
     45             free(cur->key);
     46             /* value is just part of the struct */
     47             next = cur->__next;
     48             free(cur);
     49             cur = next;
     50         }
     51     }
     52     free((void *)self);
     53 }
     54 
     55 void __HashMapIter_del(struct HashMapIter* self) {
     56     free((void *)self);
     57 }
     58 
     59 int getBucket(char *str, int buckets)
     60 {
     61     int hash = 42;
     62     if ( str == NULL ) return 0;
     63     for( ; *str ; str++) {
     64         hash = ( hash << 3 ) ^ *str;
     65     }
     66     return hash % buckets;
     67 }
     68 
     69 void __HashMap_dump(struct HashMap* self)
     70 {
     71     int i;
     72     struct HashMapEntry *cur;
     73     printf("Object HashHashMap count=%d buckets=%d\n", self->__count, self->__buckets);
     74     for(i = 0; i < self->__buckets; i++ ) {
     75         for(cur = self->__heads[i]; cur != NULL ; cur = cur->__next ) {
     76             printf(" %s=%d [%d]\n", cur->key, cur->value, i);
     77         }
     78     }
     79 }
     80 
     81 #include "student.c"
     82 
     83 struct HashMapIter* __HashMap_iter(struct HashMap* map)
     84 {
     85     struct HashMapIter *iter = malloc(sizeof(*iter));
     86     iter->__map = map;
     87     iter->__bucket = 0;
     88     iter->__current = map->__heads[iter->__bucket];
     89     iter->next = &__HashMapIter_next;
     90     iter->del = &__HashMapIter_del;
     91     return iter;
     92 }
     93 
     94 struct HashMap * HashMap_new() {
     95     struct HashMap *p = malloc(sizeof(*p));
     96     int i;
     97 
     98     p->__buckets = 8;
     99     for(i=0; i < p->__buckets; i++ ) {
    100         p->__heads[i] = NULL;
    101         p->__tails[i] = NULL;
    102     }
    103 
    104     p->__count = 0;
    105 
    106     p->put = &__HashMap_put;
    107     p->get = &__HashMap_get;
    108     p->size = &__HashMap_size;
    109     p->dump = &__HashMap_dump;
    110     p->iter = &__HashMap_iter;
    111     p->del = &__HashMap_del;
    112     return p;
    113 }
    114 
    115 int main(void)
    116 {
    117     struct HashMap * map = HashMap_new();
    118     struct HashMapEntry *cur;
    119     struct HashMapIter *iter;
    120 
    121     setvbuf(stdout, NULL, _IONBF, 0);  /* Internal */
    122 
    123     printf("Testing HashMap\n");
    124     map->put(map, "z", 8);
    125     map->put(map, "z", 1);
    126     map->put(map, "y", 2);
    127     map->put(map, "b", 3);
    128     map->put(map, "a", 4);
    129     map->dump(map);
    130 
    131     printf("size=%d\n", map->size(map));
    132 
    133     printf("z=%d\n", map->get(map, "z", 42));
    134     printf("x=%d\n", map->get(map, "x", 42));
    135 
    136     printf("\nIterate\n");
    137     iter = map->iter(map);
    138     while(1) {
    139         cur = iter->next(iter);
    140         if ( cur == NULL ) break;
    141         printf(" %s=%d\n", cur->key, cur->value);
    142     }
    143     iter->del(iter);
    144 
    145     map->del(map);
    146 }