ハシ・マプを実装せむとす
言語は C11 とす.また,要素の型は int
に限定することとす.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct hashitem {
char* key;
int value;
};
struct hashmap {
struct hashitem* head;
unsigned int size;
unsigned int max_size;
};
void add_hashmap(struct hashmap* hmp, char* key, int val);
int hash(char* str, int max_v) {
int v = 0;
while(*str != '\n') v += *str++;
return v % max_v;
}
struct hashmap init_hashmap(unsigned int init_size) {
struct hashmap hm;
struct hashitem* hip = (struct hashitem*) malloc(sizeof(struct hashitem) * init_size);
if(hip == NULL) {
printf("ERROR\n");
exit(1);
}
for(int i=0; i<init_size; i++) {
struct hashitem hi;
hi.key = "";
hi.value = 0;
*(hip + i) = hi;
}
hm.head = hip;
hm.size = 0;
hm.max_size = init_size;
return hm;
}
struct hashmap rehash(struct hashmap oldmap) {
unsigned int size = oldmap.max_size << 1;
struct hashmap hm = init_hashmap(size);
struct hashitem* p = oldmap.head;
for(int i=0; i<oldmap.max_size; i++) {
struct hashitem item = *(p + i);
if(strcmp(item.key, "") == 0) continue;
add_hashmap(&hm, item.key, item.value);
}
free(oldmap.head);
return hm;
}
void add_hashmap(struct hashmap* hmp, char* key, int val) {
struct hashmap hm = *hmp;
if(hm.size + 1 == hm.max_size) {
struct hashmap new_hm = rehash(hm);
*hmp = new_hm;
hm = new_hm;
}
int index = hash(key, hm.max_size);
while(1) {
struct hashitem item = *(hm.head + index);
if (strcmp(item.key, "") == 0) break;
index = (index + 1) % hm.max_size;
}
struct hashitem hi;
hi.key = key;
hi.value = val;
*(hm.head + index) = hi;
hmp->size += 1;
}
int get_hashmap(struct hashmap hm, char* key) {
int index = hash(key, hm.max_size);
struct hashitem hi;
while(1) {
hi = *(hm.head + index);
if (strcmp(hi.key, key) == 0) break;
index = (index + 1) % hm.max_size;
}
return hi.value;
}
int main() {
struct hashmap hm = init_hashmap(4);
add_hashmap(&hm, "magic", 12);
add_hashmap(&hm, "hac", 34);
add_hashmap(&hm, "hashmap", 56);
add_hashmap(&hm, "dict", 78);
add_hashmap(&hm, "unordered_map", 90);
int val = get_hashmap(hm, "magic");
printf("%d\n", val);
return 0;
}
int
型以外に対応せしむるには, value の型を変更すべし.また,今回 hashitem
に於て値を宛ら包むが,ポインタで代用するを得.