给定集合的数据结构,测试两个集合的相等似乎是一个理想的任务,实际上许多实现允许这样做(例如python中的内置集合)。
Erlang中有不同的集合实现:sets
,ordsets
,gb_sets
。他们的文档没有说明是否可以使用术语比较来测试相等性(" =="),它们也不提供用于测试相等性的显式函数。
一些天真的案例似乎允许使用" =="进行同等性测试,但我有一个更大的应用程序,我可以生成sets
和gb_sets
是相等的(使用下面的函数测试),但不要与" =="进行比较。对于ordsets
,他们总是比较平等。遗憾的是,我还没有找到一种方法来生成一个最小的例子,其中相等的集合与" =="
为了可靠地测试相等性,我使用以下函数,基于此theorem on set equality:
%% @doc Compare two sets for equality.
-spec sets_equal(sets:set(), sets:set()) -> boolean().
sets_equal(Set1, Set2) ->
sets:is_subset(Set1, Set2) andalso sets:is_subset(Set2, Set1).
我的问题:
sets
的最小示例,其中" =="给出上述代码时,不比较相等,但这些集合相等?关于问题2的一些想法:
sets
州的文档,"未定义集合的表示。"作为ordsets
状态的文档,其中" ordset是集合的表示"。 gb_sets
上的文档没有提供任何类似的指示。
来自source code of the sets
implementation的以下评论似乎重申了文档中的陈述:
请注意,由于键的顺序未定义,我们可以自由地重新排序存储桶中的键。
我的解释是,与" =="在Erlang中,对集合的表示起作用,即如果它们的表示相同,则两个集合仅相等。这可以解释不同集合实现的不同行为,但也强化了问题,为什么没有明确的相等比较。
答案 0 :(得分:5)
ordsets
被实现为排序列表,并且实现相当开放并且可见。他们将比较相等(==
),但==
表示1.0等于1.他们不会比较严格相等(=:=
)。
sets
被实现为哈希表的一种形式,其内部表示不适用于任何形式的直接比较;当哈希冲突发生时,添加的最后一个元素被添加到给定哈希条目的列表中。此前置操作对添加元素的顺序很敏感。
gb_sets
被实现为一般的平衡树,树的结构确实取决于元素的插入顺序以及何时进行重新平衡。直接比较它们是不安全的。
要将两组相同类型的数据进行比较,一种简单的方法是调用Mod:is_subset(A,B) andalso Mod:is_subset(B,A)
- 当两组相等时,它们只能是彼此的子集。