3

リストをトラバースして、すべての要素とその要素を除く要素でいくつかの計算を行う必要があります。たとえば、リストがある場合、(1 2 3 1)ペア、、、(1) (2 3 1)およびが必要です。(2) (1 3 1)(3) (1 2 1)(1) (2 3 1)

4

3 に答える 3

5

(...)すべての要素とその要素を除く要素。

すべての要素で。のように聞こえmapます。その要素を除外すると、のように聞こえfilterます。後者から始めましょう。

user=> (filter #(not= % 1) '(1 2 3))
(2 3)

素晴らしい。それでは、すべての要素にマッピングしてみましょう。

user=> (let [coll '(1 2 3)] (map (fn [elem] (filter #(not= % elem) coll)) coll))
((2 3) (1 3) (1 2))

実際のペアを作成することは、読者の練習問題として残されています。ヒント:で使用されているクロージャーを変更しmapます。

上記の解決策は短いリストでは問題なく機能するはずですが、複雑さはO(n²)であることに注意してください。もう1つの問題は、重複するコレクションが正しく処理されないという事実です。

代わりに再帰的なアプローチを取りましょう。再帰はとに基づいloopていrecurます。

(defn pairs [coll]
  (loop [ahead coll behind [] answer []]
    (if (empty? ahead)
      answer
      (let [[current & remaining] ahead]
        (recur remaining
               (conj behind current)
               (conj answer [(list current)
                             (concat behind remaining)]))))))

ささいな例:

user=> (pairs '(1 2 3))
[[(1) (2 3)] [(2) (1 3)] [(3) (1 2)]]

重複するベクトル:

user=> (pairs [1 5 6 5])
[[(1) (5 6 5)] [(5) (1 6 5)] [(6) (1 5 5)] [(5) (1 5 6)]]
于 2012-11-28T14:04:36.323 に答える
5

リスト内包の仕事のようです:

(defn gimme-pairs [coll]
  (for [x coll]
    [(list x) (remove #{x} coll)]))

user=> (gimme-pairs [1 2 3])
([(1) (2 3)] [(2) (1 3)] [(3) (1 2)])

実際には、単一要素のリストの作成をスキップします。これにより、コードがさらに簡単になります。

(defn gimme-pairs [coll]
  (for [x coll]
    [x (remove #{x} coll)]))

user=> (gimme-pairs [1 2 3])
([1 (2 3)] [2 (1 3)] [3 (1 2)])

複製を保持する必要がある場合は、インデックス付きコレクションを使用できます。

(defn gimme-pairs [coll]
  (let [indexed (map-indexed vector coll)
        remove-index (partial map second)]
    (for [[i x] indexed]
      [x (remove-index (remove #{[i x]} indexed))])))

user=> (gimme-pairs [1 2 3 1])
([1 (2 3 1)] [2 (1 3 1)] [3 (1 2 1)] [1 (1 2 3)])
于 2012-11-28T19:50:34.067 に答える
1
(def l [1 2 3])

(first (reduce (fn [[res ll] e]
                 [(conj res [(list e) (rest ll)])
                  (conj (vec (rest ll)) e)])
               [[] l] l))
=> [[(1) (2 3)] [(2) (3 1)] [(3) (1 2)]]
于 2012-11-28T17:24:44.223 に答える