[英]What is the purpose of sorted sets?
Clojure有一個函數sorted-set
,用於創建PersistentTreeSet
對象。 顧名思義, sorted-set
創建了一個排序的唯一對象集合。
什么時候排序集有用嗎? 什么時候使用sorted-set
比sort
和distinct
更好?
=> (apply sorted-set [2 2 1 1 3 3])
#{1 2 3}
=> (sort (distinct [2 2 1 1 3 3]))
(1 2 3)
當您需要設置語義時,排序集很有用 - 快速contains?
,如Leon所解釋的那樣, conj
和disj
(=元素刪除) - 以及定義良好的順序遍歷。 在內置有序集(和映射)的情況下,有序遍歷可以在整個集合( seq
, rseq
)和兩個密鑰之間的任何“子范圍”( subseq
, rsubseq
),包括或排除。
如果你願意接觸核心外的集合,那么Contrib庫data.avl (我是作者和維護者)提供了一系列帶有附加功能的排序集和映射 - 用於訪問集合元素的nth
rank, rank-of
用於發現集合中元素的等級,最近鄰居查詢,以及返回輸入集合的完整功能子集的“子范圍”和類似分割的操作(認為subseq
返回原始的完整功能子集 ,不僅僅是seq,沒有為了GC的目的而保留子集中不存在的原始元素。 所有這些都在最壞情況下的O(log n)時間內運行,就像標准的有序集合操作一樣。
如果你只需要contains?
+ conj
+ disj
,你可能會想要使用哈希集,因為它們往往會為這些操作提供更好的性能。 但是,值得注意的是,如果您反對從可能惡意的外部源添加輸入到您的集合,即使您不關心訂單,您也可能希望使用有序集合。 這是因為在存在哈希沖突的情況下哈希集的性能會降低到O(n)(攻擊者可以強制使用,使用的哈希函數是確定性的並且事先是固定的),而有序集'O(log n)是很難保證。
如果您只需要對輸入集合進行一次排序,然后重復遍歷整個或各種前綴/后綴,那么構建獨特項目的排序向量可能確實是更好的選擇。 如果你需要從subseq
的任意元素開始的subseq
/ rsubseq
特性( (subseq a-set >= 5)
= seq,那么排序集可能仍然是優選的,即使對於僅遍歷工作負載也是subseq
。 a-set
相對於a-set
的排序> = 5)。
就個人而言,如果我想要一個沒有重復的有序數據結構,我會使用有序集合,因為我添加元素。也就是說,我從一個空集開始,而不是將它應用於列表。
我將使用sort和distinct的時間是,如果我有任何其他數據結構,如我想要訂購的列表和刪除重復項。
基本上,應用集合會為您提供具有唯一元素的新對象,而不同的元素會對同一列表引用起作用。
有序集與調用sort
和distinct
的結果之間的distinct
在於結果類型是一個集合。
這為你提供了O(log N)性能(想想二元搜索)來檢查一個元素是否在集合中( contains?
)或者添加一個( conj
),而在列表中,通過sort
返回並且distinct
你會變得更糟默認情況下實現相同行為的特征。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.