2017-01-08 54 views
4

Clojure中是否有雙端隊列?我的印象是Clojure的PersistentQueue是單端(我錯了嗎?)。我需要能夠從隊列的任何一端刪除數據(即「pop」)和「peek」。我對雙頭隊列的解釋是https://en.wikipedia.org/wiki/Double-ended_queueClojure中的雙端隊列

我看到Java有一個雙端隊列,但我不確定如何在Clojure中實例化隊列對象。 嘗試創建一個新的隊列:

(java.util.Dequeue.) 

給出錯誤:

No matching ctor found for interface java.util.Queue.

回答

6

Is there a double-ended queue in Clojure?

AFAIK沒有。

My impression is Clojure's PersistentQueue is single ended (am I wrong?).

它只允許conj在結束和從開始peek/pop

I see that Java has a double-ended queue, but I'm unsure how to instantiate the queue object in Clojure.

無法實例java.util.Queue,因爲它是一個interface。看一看子接口java.util.Deque與其實現類:

您可以創建和使用,例如,一個ArrayDeque如下:

(def deque (java.util.ArrayDeque. [1 2 3])) 
;;=> 'user/deque 

(.pollFirst deque) 
;;=> 1 

但是,您可能希望查看deque-clojure,它提供了Clojure中的持久實現,而不是在interop語法和可變集合中掙扎。

+0

非常感謝。其實在我的問題中,我的意思是** java.util.DeQueue **而不是** java.util.Queue **。但是,無論您的答案如何(我會糾正我的問題)。特別感謝java.util.ArrayDeque(它爲Deque提供了一個實現)的建議。我曾見過[deque-clojure](https://github.com/pjstadig/deque-clojure/blob/master/test/name/stadig/test/deque.clj),但希望有更簡單的東西(我不能按照代碼)。 – DarrylG

1

只是爲了completenes,純Clojure的版本可能是這樣的:

(defn deque 
    ([] 
    '[()()]) 
    ([& elems] 
    [elems '()])) 

(defn push-front [deque elem] 
    (let [[head tail] deque] 
    [(cons elem head) tail])) 

(defn push-back [deque elem] 
    (let [[head tail] deque] 
    [head (cons elem tail)])) 

(defn pop-front [deque] 
    (let [[head tail] deque] 
    (if (empty? head) 
     [(-> tail reverse rest) head] 
     [(rest head) tail]))) 

(defn pop-back [deque] 
    (let [[head tail] deque] 
    (if (empty? tail) 
     [tail (-> head reverse rest)] 
     [head (rest tail)]))) 

(defn peek-front [deque] 
    (let [[head tail] deque] 
    (if (empty? head) 
     (-> tail reverse first) 
     (first head)))) 

(defn peek-back [deque] 
    (let [[head tail] deque] 
    (if (empty? tail) 
     (-> head reverse first) 
     (first tail)))) 


;; usage example: 

user> (let [dq (deque)] 
     (-> dq 
      (push-front :a) 
      (push-front :b) 
      (peek-back))) 


:a 
user> (let [dq (deque)] 
     (-> dq 
      (push-front :a) 
      (push-front :b) 
      (pop-back))) 


[() (:b)] 

user> (let [dq (deque)] 
    (-> dq 
     (push-back :a) 
     (push-back :b) 
     (peek-back))) 
:b