2015-11-08 43 views
2

Clojure有一个功能sorted-set它创建一个PersistentTreeSet对象。顾名思义,sorted-set创建一个排序的唯一对象集合。排序集的目的是什么?

何时排序设置有用吗?什么时候使用sorted-setsortdistinct更好?

=> (apply sorted-set [2 2 1 1 3 3]) 
#{1 2 3} 
=> (sort (distinct [2 2 1 1 3 3])) 
(1 2 3) 
+0

你要问关于特别是“排序”位或为这台左右,一般? – cfrick

+0

@cfrick:我想知道你什么时候想要结合这两者。 – Zaz

回答

1

排序集合是有用的。对于内置的有序集合(和地图),可以在整个集合(seq,rseq)和两个键之间的任意“子范围”(subseqrsubseq)(包含或独占)之间进行有序遍历。

如果您愿意接触核心外收藏,Contrib图书馆data.avl(其中我是作者和维护者)提供了具有附加功能的排序集和地图的风格 - nth用于访问集排序元素,rank-of用于发现集合中元素的排名,最近邻居查询以及返回输入集合的完整功能子集的“子范围”和分裂式操作(想想subseq返回完全功能子集原始的,而不仅仅是一个seq,没有坚持GC中没有的子集中的任何元素)。所有这些操作在O(log n)时间最差的情况下,就像标准的排序集操作一样。

如果您只需要contains? + conj + disj,您可能需要使用散列集,因为它们倾向于为这些操作提供更好的性能。然而,值得注意的是,如果您预计会将可能是恶意的外部源的输入添加到您的集合中,那么即使您不关心订单,也可能想要使用排序的集合。这是因为散列集的性能在存在散列冲突的情况下会降低到O(n)(对手可能会强制执行,所使用的散列函数是确定性的并且是事先确定的),而排序集O(log n)是很难保证。

如果您只需要对输入集合进行一次排序,然后重复遍历整个或各种前缀/后缀,然后构建一个排序的独特项目向量可能确实是更好的选择。甲排序集合可以仍然是优选的,即使是仅遍历-工作量,不过,如果需要在收集的任意元素开始((subseq a-set >= 5) = SEQ超过其是> = 5相对于的a-set那些元件的subseq/rsubseq特征到a-set的排序)。

+0

神圣的莫利,你知道很多关于套!非常感谢。 – Zaz

1

就个人而言,我使用的有序集合,如果我想不重复的有序数据结构,正如我在添加元素。话虽这么说,我开始与空集,而不是将其应用到列表中。

我将使用排序和独特的时间是如果我有任何其他数据结构像列表,我想要排序和删除重复。

基本上,应用一个集合给你一个新的对象与独特的元素,同时不同行为在同一个列表引用。

+1

'distinct'返回一个新的对象(一个懒惰序列) - 就像新的和不可改变的通过施加'分拣set'返回的一个。 – Thumbnail

+0

@Thumbnail - 谢谢你回来告诉我我错了。我接受我不知道Closure的内部工作原理。欢迎您提供您自己的答案。 –

1

有序集合与调用sortdistinct的结果之间的差异是结果类型是一个集合。

这给你为O(log n)性能(认为二进制搜索),以检查一个元素是否在集合中(contains?)或添加一个(conj),而一个列表,通过sort返回和distinct你”上d得到更糟的特性,以默认实现相同的行为。快速contains?conjdisj(=元件清除),如由Leon解释 - - 和遍历在良好定义的顺序,当你需要一套语义