jvf*_*jvf 3 erlang functional-programming set
给定集合的数据结构,测试两个集合是否相等似乎是一项理想的任务,并且实际上许多实现都允许这样做(例如python中的内置集合)。
有不同的设置实现了二郎:sets,ordsets,gb_sets。他们的文档没有指出是否可以使用术语比较(“ ==”)来测试相等性,也没有提供用于测试相等性的显式功能。
某些幼稚的情况似乎允许使用“ ==”进行相等性测试,但是我有一个更大的应用程序可以在其中生成sets且gb_sets相等(使用下面的函数进行测试),但不将其与“ ==”进行比较。对于ordsets,它们总是比较相等。不幸的是,对于相等集不等于“ ==”的情况,我还没有找到产生最小示例的方法。
为了可靠地测试相等性,我基于以下关于集合相等性的定理使用以下函数:
%% @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).
Run Code Online (Sandbox Code Playgroud)
我的问题:
sets在给出上述代码的情况下,如何生成一个最小示例,其中“ ==”不等于,但集合相等?对问题2的一些思考:
有关sets状态的文档,“未定义集合的表示形式”。其中,作为ordsets状态的文档,“一个ordset是一个集合的表示”。上的文档gb_sets未提供任何可比的指示。下面的评论,从该源代码sets实现,似乎重申从文档的声明:
请注意,由于键的顺序未定义,我们可以在存储桶中自由地对键进行重新排序。
我的解释是,在Erlang中用“ ==”进行的术语比较适用于集合的表示,即两个集合仅在表示相同时比较相等。这将解释不同集合实现的不同行为,但也将进一步说明为什么没有显式的相等比较的问题。
ordsets以排序列表的形式实现,并且实现是相当开放的,并且可以看到。它们将比较equal(==),尽管==意味着1.0等于1。它们将不会严格等于(=:=)比较。
sets以哈希表的形式实现,其内部表示形式不适合任何形式的直接比较;当发生哈希冲突时,最后添加的元素会在给定哈希条目的列表之前。此前置操作对元素添加的顺序敏感。
gb_sets它们被实现为一般的平衡树,并且树的结构确实取决于元素插入的顺序以及重新平衡的发生时间。直接比较不安全。
要比较两个相同类型的集合,一种简单的方法是调用Mod:is_subset(A,B) andalso Mod:is_subset(B,A)-两个集合相等时只能是彼此的子集。