【发布时间】:2015-10-01 14:46:58
【问题描述】:
所以,我的 SFH 函数:
/*
* Hash function (found at: 'http://www.azillionmonkeys.com/qed/hash.html')
*/
int32_t SuperFastHash(const char * data, int len) {
uint32_t hash = len, tmp;
int rem;
if (len <= 0 || data == NULL) return 0;
rem = len & 3;
len >>= 2;
/* Main loop */
for (;len > 0; len--) {
hash += get16bits (data);
tmp = (get16bits (data+2) << 11) ^ hash;
hash = (hash << 16) ^ tmp;
data += 2*sizeof (uint16_t);
hash += hash >> 11;
}
/* Handle end cases */
switch (rem) {
case 3: hash += get16bits (data);
hash ^= hash << 16;
hash ^= ((signed char)data[sizeof (uint16_t)]) << 18;
hash += hash >> 11;
break;
case 2: hash += get16bits (data);
hash ^= hash << 11;
hash += hash >> 17;
break;
case 1: hash += (signed char)*data;
hash ^= hash << 10;
hash += hash >> 1;
}
/* Force "avalanching" of final 127 bits */
hash ^= hash << 3;
hash += hash >> 5;
hash ^= hash << 4;
hash += hash >> 17;
hash ^= hash << 25;
hash += hash >> 6;
// Limits hashes to be within the hash table
return hash % HT_LENGTH;
}
它看起来工作正常,(它应该因为除了最后一行之外的所有内容都没有被我触及)。
这是我将字典加载到哈希表中的函数,这似乎也很有效。
bool load(const char* dictionary)
{
// declares file pointer
FILE* dictptr = fopen(dictionary, "r");
// declare temp index
uint32_t index = 0;
// read words, one by one
while(true)
{
// malloc node
node* new_node = malloc(node_size);
// insert word into node, if fscanf couldn't scan word; we're done
if (fscanf(dictptr, "%s", new_node->word) != 1)
{
return true;
}
// hash word - HASH FUNCTION CALL -
index = SuperFastHash(&new_node->word[0], sizeof(new_node->word));
// check if head node has been assigned with value
if (!strcmp(hashtable[index].word,""))
{
// declare hashtable[index] to new_node
hashtable[index] = *new_node;
//increment size
hashtablesize++;
}
else
{
// if node is initialized, insert after head
new_node->next = hashtable[index].next;
hashtable[index].next = new_node;
//increment size
hashtablesize++;
}
}
}
最后,我的检查函数根据哈希表检查单词。
bool check(const char* keyword)
{
// gets index from SFH
uint32_t index = SuperFastHash(keyword, sizeof(keyword));
// declares head pointer to the pointer of the index'd element of hashtable
node* head = &hashtable[index];
// if word of head is equal to keyword, return true
// else continue down chain till head is null or key is found
while (head != NULL)
{
if (!strcmp(head->word, keyword))
{
return true;
}
head = head->next;
}
return false;
}
注意:当使用不同的哈希函数时,一切正常,所以我怀疑问题出在 len 参数或实际的 SFH 函数中。
我已经用 lldb 检查了返回的索引,比如“cat”不等于“cat”驻留在哈希表中的索引。即加载中函数调用返回的索引。
【问题讨论】:
-
sizeof(keyword)不正确。这只是给你一个指向char的指针的大小。根据您的系统是 32 位还是 64 位,始终为 4 或 8。应该是strlen(keyword)或strlen(keyword) + 1(取决于散列函数是否需要 NUL 终止符 - 我没有仔细看)。解决这个问题,您可能会得到正确的结果。 -
天哪,太感谢你了,应该已经看到了!再次感谢!
标签: c hashtable hash-function