【发布时间】:2021-12-18 06:07:24
【问题描述】:
我正在尝试使用哈希表存储一些数据,我决定使用 glib。
所以我可以使用 g_str_hash 来生成密钥,但是有相等的字符串。基本上,数据来自一个 csv 文件,例如,同一个 id 有多行。而且我想使用 id 作为键,并且仍然有单独的行。
所以我试图从 g_str_hash 实现一个类似的算法,但是当密钥已经附加了一些东西时,它会转到下一个可用空间。但是由于类型和如何做的一些问题,我遇到了困难。
guint hash(char * key, GHashTable *hasht ) {
unsigned int hash = 5381;
int c;
while ((c = *(key++))) {
hash = ((hash << 5) + hash) + c;
}
//this is where i get lost on how to check if there is alreay something stored using the hash I generated before
while (g_hash_table_contains(hasht, hash))
{
hash++;
}
return hash;
}
Soo 我真的很感谢一些关于如何做到这一点的帮助!非常感谢!
【问题讨论】:
-
哈希表是一个数组加上一个链表(一般使用forward-chaining进行列表插入)。您的阵列为您的桌子保存桶。每个桶的内容是一个指向节点的指针(或
NULL)。它也是链表的head节点,该链表从该存储桶开始,在发生冲突时添加到该存储桶中。您可能会发现 Coding up a Hash Table 和 Hash tables - eternally confuzzled 很有用。 -
while (g_hash_table_contains(hasht, hash))正在检查是否发生了冲突。hast++试图通过将1添加到哈希中来避免冲突(如果您还想将信息取回,那将是灾难的根源)。根据我使用glib的经验,它尽最大努力向您隐藏详细信息,并为您提供从哈希表中添加、查找和删除的工具。见GLib-HashTable(我讨厌新的黑色 glib/gtk 文档方案——它很难看) -
@DavidC.Rankin 非常感谢!但这只有在我从头开始创建哈希表时才有效,对吗?如果我使用 glib,是否实现了链表?
-
@DavidC.Rankin 哦,谢谢你让我知道,因为我确实需要找回信息!所以你会建议我从头开始创建我的哈希表吗?
-
使用 glib 哈希表很好。它为您处理冲突和列表创建。当您添加到哈希表时,如果发生冲突,您正在存储的节点会自动添加到从该节点开始的链表中。当您从散列表中检索信息时,您的值会被散列,它指定存储桶以开始在列表中搜索项目,并处理比较以匹配链接列表中的项目。只需使用 glib 提供的哈希表函数(感觉有点盲目——但这就是重点)。否则,你必须重新发明轮子。