虽然这个问题与c ++有关,但它是一个普遍的哈希问题,也可以回答其他语言。
我有一个由 标识的类,它拥有2个成员中的一个(让我们称之为设备和名称)。
class Foo {
static const int NO_DEVICE = 0;
bool isDeviceSet() {
return device != NO_DEVICE;
}
private:
int device;
std::string name;
};
我想确定一个Foo
实例,其优先级为device
(当设置时)。
这意味着,当设置device
时,我想根据device
(单独! - 进行哈希处理 - 以便两个Foo
具有相同的device
并且不同的name
将被视为相同的对象哈希)
如果device
未设置,我想根据name
进行哈希。
我的问题:
其中一个成员是否足够安全?
例如,任何一个散列都是这样的:
namespace std {
size_t hash<Foo>::operator()(Foo const& f) const {
if (f.isDeviceSet()) {
return std::hash<int>()(f.deviceId);
}
return std::hash<std::string>()(f.name);
}
}
这个问题是,人们可以争辩(根据每个哈希函数的实现),2个不同Foo
的概率,一个device
集,一个没有{{1设置,拥有相同的哈希码是未知的(但不太可能)。
device
和Foo{2, "bar"}
具有相同的哈希码。另一方面,我不确定在散列中合并Foo{0, "2"}
是否会给出更好的结果(对于一般情况 - 显然它解决了上面子弹中的示例):
isDeviceSet()
欢迎任何见解/其他哈希想法。
答案 0 :(得分:3)
哈希总是与平等相结合。
您需要定义一个与您认为相等的元素匹配的相等操作,并且与您认为不相等的元素不匹配。
然后定义一个哈希函数,该函数必须具有相等认为等于相同哈希码的所有元素。对于被认为不相等的元素,根本没有要求。
任何涉及散列的算法都必须在不等对象的相同哈希码中存活而没有问题;如果存在比可能的哈希码更多的可能对象,则永远不可能保证不同对象的不同哈希码。即使您的哈希函数返回0,任何使用它的算法都应该正常工作,除非可能效率较低。
当您考虑制作哈希函数的复杂程度时:它应该只是使具有相同哈希码的现有对象的集合变小。除非你有一个真正性能至关重要的哈希表,否则它不一定非常完美。但是哈希函数本身在某种程度上也是性能关键。