2017-01-08 9 views
4

Clojureにはダブルエンドキューがありますか?私の印象はClojureのPersistentQueueはシングルエンドです(私は間違っていますか?)。キューのいずれかの端からデータを削除(つまり「ポップ」)し、「覗く」ことができる必要があります。ダブルエンドキューの意味については、https://en.wikipedia.org/wiki/Double-ended_queueです。Clojureのダブルエンドキュー

Javaには両端キューがありますが、Clojureでキューオブジェクトをインスタンス化する方法は不明です。で新しいキューを作成しようとしました :

(java.util.Dequeue.) 

はエラーを与える:

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

答えて

6

Is there a double-ended queue in Clojure?

私の知る限りありません。

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

それはほんの始まりから終わりconjpeek/popすることができます。

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

それはinterfaceだからあなたはjava.util.Queueをインスタンス化することはできません。サブインターフェイスjava.util.Dequeとその実装クラスを見てください:

次のようにあなたは、たとえば、ArrayDequeを作成して使用することができます:

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

(.pollFirst deque) 
;;=> 1 

しかし、interop構文や可変コレクションと闘うのではなく、Clojureで永続的な実装を提供するdeque-clojureをチェックしてみてください。

+0

おかげで多くのことを。実際に私の質問では、** java.util.Queue **ではなく** java.util.DeQueue **を意味していました。しかし、あなたの答えは関係なく保持されます(私は私の質問を修正するでしょう)。 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