哈希表在表中的每个条目处使用链接列表。哈希码算法生成索引。哈希码算法的输入是键/值对中的键。哈希码算法采用 char* 输入并输出整数索引。 Hashtable Get/Set 方法可以通过使用 void* 和数据大小来获取任何类型的输入。为了生成几乎唯一的索引,输入字符串必须是唯一的,但 Set/Get 函数需要彼此对应,以便如果 Set 函数中的键是“foobar”,则稍后使用“foobar”映射对 Get 的调用到相同的哈希表索引。
问题是输入是 void* 并且需要一个唯一的字符串来生成索引,那么我唯一能想到的是使用链接列表中节点中键的唯一内存地址的字符串表示形式,将存储在哈希表中的该索引处。
设置函数(部分示例代码)
struct Node* node_to_set = Node_Create(entry->key, entry->data, entry->keysize, entry->datasize);
void* key = Node_Get_Key(node_to_set);
char string_key[256] = {'\0'};
int bytes = sprintf(string_key, "%p", key);
int index = Hashtable_HashCode(hashtable->size, string_key);
获取函数(外部调用者会丢失该唯一字符串)
//do not know what the memory address is because its in the table
//searching for it would defeat the purpose of a constant time lookup
还有其他方法可以使用 void* 来做到这一点吗?
最佳答案
而不是使用内存地址的字符串表示形式传递给哈希函数。我使用了解除引用的值,该值是唯一的,因为它是一个键。我通过将 void* 转换为 unsigned char* 来取消引用它,然后将其传递给哈希函数。
int index = Hashtable_HashCode(hashtable->size, (unsigned char*)entry->key);
unsigned long Hashtable_HashCode(unsigned int size, unsigned char *str) {
if(str != NULL) {
unsigned long hash = 5381;
unsigned int c = 0;
while(c = *str++) {
hash = ((hash << 5) + hash) + c;
}
hash = hash % size;
hash = (hash < 0) ? hash * -1 : hash;
return hash;
}
return -1;
}
关于C 哈希表设置/获取 void* 唯一内存地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44480520/