Clojure:シーケンスからシーケンシャルアイテムを見つける

StackOverflow https://stackoverflow.com/questions/2720958

  •  01-10-2019
  •  | 
  •  

質問

Clojureプログラムでは、一連の数字があります。

(2 3 4 6 8 1)

アイテムがシーケンシャルである最も長いサブシーケンスを見つけたいです。

(2 3 4)

私はそれが関与すると仮定しています (take-while ...) また (reduce ...).

何か案は?

説明: :シーケンシャルアイテムの最長の初期リストが必要です。はるかに簡単です。私が最初に提起したより困難な問題の解決策をありがとう。

役に立ちましたか?

解決

あなたが最も長い初期シーケンスにのみ興味があるなら、それは1ライナーです:

(defn longest-initial-sequence [[x :as s]]
  (take-while identity (map #(#{%1} %2) s (iterate inc x))))

他のヒント

質問に対するOPのコメントを考慮に入れて、ゲームを完全に変更します! - これは非常に簡単に書くことができます:

(let [doubletons (partition 2 1 [1 2 3 5 6])
      increment? (fn increment? [[x y]]
                   (== (inc x) y))]
  (cons (ffirst doubletons)
        (map second (take-while increment? doubletons))))

;; returns (1 2 3)

これは実際には怠zyであることに注意してください。私はそれがの頭を保持しないことを期待しています doubletons 地元の人々のクリアに感謝します。別のバージョン:

(cons (first [1 2 3 5 6])
      (map second (take-while increment? (partition 2 1 [1 2 3 5 6]))))

しかし、質問の元のバージョンはもっと楽しいです! :-)それに対する非常に単純なソリューションは上記を使用して構築できますが、もちろん、それは使用よりもパフォーマンスが大幅に少なくなります reduce. 。このスレッドのその部分を後で追加するために、ZmilaやDnolenのソリューションとは実質的に異なるものがあるかどうかを確認します。 (おそらくそうではないと思います。)

オリジナルへの回答:

(defn conj-if-sequential
  ([] [])
  ([a] a)
  ([a b] (let [a (if (vector? a) a [a])]
           (if (= (inc (last a)) b)
             (conj a b)
             a))))

(reduce conj-if-sequential [2 3 4 6 8 1])

興味のある人のためのより一般的なソリューション:

(defn sequential-seqs
  ([] [])
  ([a] a)
  ([a b] (let [n (last (last a))]
           (if (and n (= (inc n) b))
             (update-in a [(dec (count a))] conj b)
             (conj a [b])))))

(defn largest
  ([] nil)
  ([a] a)
  ([a b] (if (> (count b) (count a)) b a)))

(reduce largest (reduce sequential-seqs [] [2 3 4 6 8 1 4 5 6 7 8 9 13]))

これはずっと良いと思います。

(defn find-max-seq [lst]
  (let [[f & r] lst, 
        longest-seq (fn [a b] (if (> (count a) (count b)) a b)),
        [last-seq max-seq] (reduce 
                             (fn [ [[prev-num & _ :as cur-seq] max-seq] cur-num ]
                               (if (== (inc prev-num) cur-num) 
                                 [(conj cur-seq cur-num) max-seq]
                                 [(list cur-num) (longest-seq cur-seq max-seq)]
                                 ))
                             [(list f) ()]
                             r)]
    (reverse (longest-seq last-seq max-seq))))

(find-max-seq '(2 3 4 6 8 1))  ; ==> (2 3 4) 
(find-max-seq '(3 2 3 4 6 8 9 10 11)) ; ==> (8 9 10 11)
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top