This repository has been archived on 2026-05-11. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
prog-103-p-03-2030/AcquiringLand/Fundamentals/minefield.c
T
2026-02-03 23:15:17 +01:00

193 lines
4.0 KiB
C

#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
struct pair_list
{
const char *key;
char *value;
struct pair_list *next;
};
struct hash_map
{
struct pair_list **data;
size_t size;
};
size_t hash(const char *key)
{
if (!key)
return 0;
uint32_t hash = 2166136261;
uint32_t prime = 16777619;
while (*key)
{
hash ^= *key;
hash *= prime;
key++;
}
return hash;
}
struct hash_map *hash_map_init(size_t size)
{
struct hash_map *res = malloc(sizeof(struct hash_map));
if (!res)
return NULL;
res->data = calloc(size, sizeof(struct pair_list *));
if (!res->data)
{
free(res);
return NULL;
}
res->size = size;
return res;
}
bool hash_map_insert(struct hash_map *hash_map, const char *key, char *value,
bool *updated)
{
if (!hash_map || hash_map->size == 0 || !key)
return false;
size_t hashed_val = hash(key) % hash_map->size;
struct pair_list *elt = hash_map->data[hashed_val];
while (elt)
{
if (strcmp(key, elt->key) == 0)
break;
elt = elt->next;
}
if (!elt)
{
struct pair_list *new = calloc(1, sizeof(struct pair_list));
if (!new)
return false;
new->key = key;
new->value = value;
struct pair_list *res = hash_map->data[hashed_val];
new->next = res;
hash_map->data[hashed_val] = new;
if (updated)
*updated = false;
return true;
}
elt->value = value;
if (updated)
*updated = true;
return true;
}
void hash_map_free(struct hash_map *hash_map)
{
if (!hash_map)
return;
for (size_t i = 0; i < hash_map->size; i++)
{
struct pair_list *elt = hash_map->data[i];
while (elt)
{
struct pair_list *n = elt->next;
free(elt);
elt = n;
}
}
free(hash_map->data);
free(hash_map);
hash_map->data = NULL;
}
void hash_map_dump(struct hash_map *hash_map)
{
if (!hash_map)
return;
for (size_t i = 0; i < hash_map->size; i++)
{
struct pair_list *elt = hash_map->data[i];
while (elt)
{
printf("%s: %s", elt->key, elt->value);
elt = elt->next;
if (elt)
printf(", ");
else
putchar('\n');
}
}
}
const char *hash_map_get(const struct hash_map *hash_map, const char *key)
{
if (!hash_map || hash_map->size == 0)
return NULL;
size_t hashed_val = hash(key) % hash_map->size;
struct pair_list *elt = hash_map->data[hashed_val];
while (elt)
{
if (strcmp(key, elt->key) == 0)
break;
elt = elt->next;
}
if (elt)
return elt->value;
return NULL;
}
bool hash_map_remove(struct hash_map *hash_map, const char *key)
{
if (!hash_map || hash_map->size == 0)
return false;
size_t hashed_val = hash(key) % hash_map->size;
struct pair_list *elt = hash_map->data[hashed_val];
struct pair_list *prev = NULL;
while (elt)
{
if (strcmp(key, elt->key) == 0)
break;
prev = elt;
elt = elt->next;
}
if (!elt)
return false;
if (prev)
prev->next = elt->next;
else
hash_map->data[hashed_val] = elt->next;
free(elt);
printf("removed %s", elt->value);
return true;
}
int main(void)
{
struct hash_map *map = hash_map_init(10);
if (!map)
return 1;
bool updated;
hash_map_insert(map, "key1", "value1", &updated);
hash_map_insert(map, "key2", "value2", &updated);
hash_map_insert(map, "key1", "new_value1", &updated);
hash_map_dump(map);
const char *val = hash_map_get(map, "key1");
if (val)
printf("Retrieved key1: %s\n", val);
hash_map_remove(map, "key2");
hash_map_dump(map);
hash_map_free(map);
printf("Everything is ok!\n");
return 0;
}