【发布时间】:2014-03-17 21:28:54
【问题描述】:
所以我正在开发一个使用哈希表的程序。事情是这样的:
1) 将文本文件读入“符号”对象的向量(包含名称和数字) 2) 散列 Symbol 对象的名称。 3) 将此对象插入到哈希表中。
到目前为止,我一直将唯一生成的哈希键存储为整数数组。然后我循环遍历数组,看看是否有重复。
如果有,我知道有碰撞。然而,这种方法已被证明是成功的,现在我必须编写一个 rehash() 函数,这样我才能获得一个不会导致冲突的新密钥。但我无法弄清楚如何做到这一点。
我已经包含了我的循环,我在其中检查键数组和我当前的哈希函数以及我的输出。任何关于去哪里的建议将不胜感激。
for (int i=0; i < TABLE_SIZE; i++)
{
if (i != j)
{
if (array[i] == array[j])
{
cout << endl;
cout << "Collision occurred at" << array[i] << endl;
cout << "Now rehashing..." << endl;
// REHASH FUNCTION SHOULD GO HERE --> rec.key = rehash(data);
cout << "The new key is: " << rec.key << endl;
break;
}
}
}
dataTable.insert(rec); //inserts the record object into the HashTable.
现有哈希函数:
int hasher (string data)
// POST: the index of entry is returned
{ int sum = 0;
for (int k = 0; k < data.length(); k++)
sum = sum + int(data[k]);
return sum % TABLE_SIZE;
}
我得到的输出:
计数 2 这个 Symbol 对象的键是:7
num
2
The key for this Symbol object is: 0
Collision occurred at0
Now rehashing...
The new key is: 1
myFloat
4
The key for this Symbol object is: 18
myDouble
5
The key for this Symbol object is: 14
name
6
The key for this Symbol object is: 18
Collision occurred at18
Now rehashing...
The new key is: 1
address
6
The key for this Symbol object is: 7
Collision occurred at7
Now rehashing...
The new key is: 1
salary
5
The key for this Symbol object is: 1
gpa
4
The key for this Symbol object is: 18
Collision occurred at18
Now rehashing...
The new key is: 1
gdp
5
The key for this Symbol object is: 0
Collision occurred at0
Now rehashing...
The new key is: 1
pi
5
The key for this Symbol object is: 7
Collision occurred at7
Now rehashing...
The new key is: 1
city
6
The key for this Symbol object is: 0
Collision occurred at0
Now rehashing...
The new key is: 1
state
6
The key for this Symbol object is: 20
county
6
The key for this Symbol object is: 2
ch
0
The key for this Symbol object is: 14
Collision occurred at14
Now rehashing...
The new key is: 1
ch2
0
The key for this Symbol object is: 1
Collision occurred at1
Now rehashing...
The new key is: 1
ID
1
The key for this Symbol object is: 15
studentID
1
The key for this Symbol object is: 13
max
3
The key for this Symbol object is: 11
max2
3
The key for this Symbol object is: 19
greeting
6
The key for this Symbol object is: 13
Collision occurred at13
Now rehashing...
The new key is: 1
debt
5
如您所见,当发生碰撞时,它会成功检测到它。现在我只需要一种重新哈希密钥的方法,这样它就不会在将来发生......因为现在重新哈希也是一个冲突。
【问题讨论】:
-
你在实现哈希表吗?然后典型的设计是使用一个散列函数,接受会有冲突(注意几个散列函数只能勉强降低冲突的几率),并使用开放寻址或单独链接解决冲突。为什么你认为你需要另一个哈希函数?
-
您实际上想要完成什么?你不只是使用 std::hash_map/std::unordered_map 有什么原因吗?
-
@delnan 是的,我正在植入一个哈希表,并且我通过单独的链接这样做并且我已经成功完成了。但是当发生冲突时,我需要重新散列字符串并重新插入表中。这是我的决心部分。
-
重新散列仍然不能保证您不会再次发生冲突。保证这一点的唯一方法是知道在编译时可能必须散列的所有键,并选择一个散列函数,将每个键映射到不同的散列桶。对于直到运行时才知道的任意字符串(或者实际上大多数数据,其中往往变化的位数大于哈希函数结果类型中的数字),这是不切实际的,您必须处理碰撞。
-
@user2704533 如果这是您的冲突解决策略,那么您没有使用单独的链接。实际上,它甚至不是一个合适的冲突解决策略,因为(正如 Tony D 也解释的那样),它实际上不起作用。您应该使用有效的冲突解决策略,一个好的开始是单独的链接或开放寻址。有一些哈希表使用多个哈希函数,但研究人员花了很长时间才让它们正常工作,如果你在他们的工作基础上构建,你会知道它的名字(例如布谷鸟哈希)。所以不要这样尝试。从小处着手。