Ocaml 哈希表中的相等性
Ocaml 中是否有哈希表在测试键相等时使用 ==
而不是 =
? 例如:
# type foo = A of int;;
# let a = A(1);;
# let b = A(1);;
# a == b;;
- : bool = false
# a = b;;
- : bool = true
# let h = Hashtbl.create 8;;
# Hashtbl.add h a 1;;
# Hashtbl.add h b 2;;
# Hashtbl.find h a;;
- : int = 2
# Hashtbl.find h b;;
- : int = 2
我想要一个可以区分 a
和 b
的哈希表。这可能吗?
Are there hashtables in Ocaml that use ==
instead of =
when testing for equality of keys?
For example:
# type foo = A of int;;
# let a = A(1);;
# let b = A(1);;
# a == b;;
- : bool = false
# a = b;;
- : bool = true
# let h = Hashtbl.create 8;;
# Hashtbl.add h a 1;;
# Hashtbl.add h b 2;;
# Hashtbl.find h a;;
- : int = 2
# Hashtbl.find h b;;
- : int = 2
I'd like a hashtable that can distinguish between a
and b
. Is that possible?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以使用自定义哈希表:
然后在代码中使用
H
而不是Hashtbl
。You can use custom hashtables:
And then use
H
instead ofHashtbl
in your code.托马斯和卡戈的答案中的解决方案在功能上是正确的。如果您按原样使用他们的解决方案,可能会困扰您的一个问题是,如果您散列许多对于
(=)
相等而对于(= 不同的键,您将遇到比预期更多的冲突=)
。事实上,对于(=)
来说,所有相等的键都具有相同的Hashtbl.hash
哈希值,并且最终位于同一个存储桶中,在那里它们被识别为不同的 (因为您要求将(==)
用作相等函数)并创建不同的绑定。在最坏的情况下,哈希表的行为与关联列表具有相同的复杂性(顺便说一下,这是您可以使用的另一种数据结构,然后您不必担心提供哈希函数)。如果您可以接受偶尔更改的值的键(因此无法从哈希表中检索该值,因为绑定位于错误的存储桶中),则可以使用以下低级函数作为哈希:
已实现在 C 中为:
然后您将使用:
The solution in Thomas and cago's answers is functionally correct. One issue that may trouble you if you use their solution as-is is that you will get more collisions than expected if you hash many keys that are equal for
(=)
and different for(==)
. Indeed, all keys that are equal for(=)
have the same hash forHashtbl.hash
, and end up in the same bucket, where they are they recognized as different (since you asked for(==)
to be used as equality function) and create different bindings. In the worst cases, the hash-table will behave with the same complexity as an association list (which, by the way, is another data structure that you could be using, and then you wouldn't have to worry about providing a hash function).If you can accept the key of a value changing occasionally (and therefore the value being impossible to retrieve from the hash-table, since the binding is then in the wrong bucket), you can use the following low-level function as hash:
Implemented in C as:
You would then use: