#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// キーの長さの最大値
#define MAX_KEY_SIZE (128)
// ハッシュの領域の大きさ
#define MAX_HASH_SIZE (4)
struct Hash{
char key[MAX_KEY_SIZE];
void *val;
};
unsigned int calcHash(const unsigned char *key){
unsigned int calc = 0;
while(*key) calc += (calc<<5) + *key++;
return ((calc >> 5) + calc) % MAX_HASH_SIZE;
}
unsigned int rehash(unsigned int calc){
return (calc+1) % MAX_HASH_SIZE;
}
void clearHash(struct Hash *hash){
hash->key[0] = '\0';
hash->val = 0;
}
void initHash(struct Hash *hash){
int i=0;
while(i++<MAX_HASH_SIZE) clearHash(hash+i);
}
void setHash(struct Hash *hash, const char *key, void *val){
int i=1;
unsigned int calc = calcHash(key);
if(*key == '\0'){ puts("NULL KEY error(set)"); exit(0); }
do{
if(strncmp(hash[calc].key, key, MAX_KEY_SIZE) == 0 || hash[calc].key[0] == '\0') break;
calc = rehash(calc);
}while(i++ < MAX_HASH_SIZE);
if(i>=MAX_HASH_SIZE){
puts("error"); exit(0);
}
strncpy(hash[calc].key, key, MAX_KEY_SIZE);
hash[calc].val = val;
}
void * getHash(struct Hash *hash, const char *key){
int i=1;
unsigned int calc = calcHash(key);
if(*key == '\0'){ puts("NULL KEY error(get)"); exit(0); }
do{
if(strncmp(hash[calc].key, key, MAX_KEY_SIZE) == 0) break;
calc = rehash(calc);
}while(i++ < MAX_HASH_SIZE);
if(i>=MAX_HASH_SIZE){
printf("'%s' is not entry.\n", key); return 0;
}
return hash[calc].val;
}
#define HV(V) ((void *)(V))
int main(int argc, char **argv){
struct Hash hash[MAX_HASH_SIZE];
initHash(hash);
setHash(hash, "a", HV(100));
printf("a: %d\n", getHash(hash, "a")); // 100
setHash(hash, "a", HV(200)); // 値を変えてみる
printf("a: %d\n", getHash(hash, "a"));
setHash(hash, "string", HV("string string")); // 文字列もいけます
printf("string: %s\n", getHash(hash, "string"));
return 0;
}