2016-08-07 8 views
1

私はいくつかのLISP関数をClojureに移行しています。Clojureで最も入れ子になったリストを取得する

(defn m 
    [list depth] 
    (cond 
     (= list nil) depth 
     (atom (first list)) (m (rest list) depth) 
     (> (m (first list) (+ depth 1)) (m (rest list) depth)) (m (first list) (+ depth 1)) 
     :default (m (rest list) depth)) 
    ) 

(defn n 
    [list depth maxdepth] 
    (cond 
     (= list nil) nil 
     (= depth maxdepth) list 
     (atom (first list)) (n (rest list) depth maxdepth) 
     (= 0 (n (first list) (+ depth 1) maxdepth)) (n (last list) depth maxdepth) 
     :default (n (first list) (+ depth 1) maxdepth)) 
    ) 

(defn myfind[mylist] 
    (n mylist 0 (m mylist 0)) 
) 

私は基本的にしたいことのように、ほとんどのネストされたリストの出力です:

(myfind '(1 2 3 (4 5) 6 ((7 8) 9))) 
=> (7 8) 

目標は、再帰を使用して最小化することで、私は、次の機能のためにStackOverflowのメッセージに問題がありますそれを達成するための組み込み関数の使用。

この場合、何が間違っていますか?

+1

'clojure.core /原子 ([X] [X&オプション]) を作成して初期のxの値と、ゼロ又はそれ以上の options'でアトムを返す... – cfrick

+0

Iを除去している原子そして私はまだスタックオーバーフローを取得し、出力は次のとおり にStackOverflowError \t ppj.core/M(フォームinit7572722406191330769.clj:4) \t ppj.core/M(フォームinit7572722406191330769.clj:6) ... これを解決する方法は非常に歓迎されています:) – Munger

+0

lこれを解決するライブラリ関数? – OlegTheCat

答えて

0
(defn- deepest-with-depth [depth s] 
    (let [nested-colls (filter coll? s)] 
    (if (seq nested-colls) 
     (mapcat (partial deepest-with-depth (inc depth)) nested-colls) 
     [[depth s]]))) 

(defn deepest [s] 
    (->> (deepest-with-depth 0 s) 
     (apply max-key first) 
     second)) 

> (deepest '(1 2 3 (4 5) 6 ((7 8) 9))) 
(7 8) 

、彼らはあなたの条件と矛盾している場合、その実装でいくつかの関数呼び出し(例えばmax-keypartial)をsubsituteお気軽に。

+0

ありがとうOlegTheCat、これです! – Munger

0
(defn- max-depth-entry [a-list] 
    (let [sub-lists (filter coll? a-list) 
     [depth list] (if (empty? sub-lists) 
          [0 a-list] 
          (apply max-key first (map max-depth-entry sub-lists)))] 
    [(inc depth) list])) 

(max-depth-entry '(1 2 3 (4 5) 6 ((7 8) 9))) 
;[3 (7 8)] 

その後

(def max-depth-sublist (comp second max-depth-entry)) 

(max-depth-sublist '(1 2 3 (4 5) 6 ((7 8) 9))) 
;(7 8) 

私はOlegTheCat's answermax-keyを使用してのアイデアを借りています。私はもともとreduceを使用して、自分を編ん:

(defn- max-depth-entry [a-list] 
    (let [sub-lists (filter coll? a-list) 
     [a-list a-depth] (reduce 
          (fn ([] [a-list 0]) 
          ([[as an :as asn] [s n :as sn]] (if (> n an) sn asn))) 
          (map max-depth-entry sub-lists))] 
    [a-list (inc a-depth)])) 

その後

(def max-depth-sublist (comp first max-depth-entry)) 

今、私が今まで私を窮地に立たさたSequs Horribilis on 4Clojure、に戻る準備ができています。ここ

0

1つのよりちょうど古典的な古い学校のソリューションを有する変異体、および無Clojureの特定のシーケンス機能がすべてである:

(defn deepest [items depth] 
    (if (sequential? items) 
    (let [[it1 d1 :as res1] (deepest (first items) (inc depth)) 
      [it2 d2 :as res2] (deepest (next items) depth)] 
     (cond (>= depth (max d1 d2)) [items depth] 
      (>= d1 d2) res1 
      :else res2)) 
    [items -1])) 

それがネストされたリストの再帰に古典的なアプローチだことで、それはまた、注目すべきである:最初に、あなたが再発carに、次にcdrに入力し、これらの結果を組み合わせてください。

user> (deepest '(1 2 3 (4 5) 6 ((7 8) 9)) 0) 
[(7 8) 2] 

user> (deepest '(1 2 3 (4 5) 6) 0) 
[(4 5) 1] 

user> (deepest '(1 2 3 (x ((y (z)))) (4 5) 6) 0) 
[(z) 4] 

user> (deepest '(1 2 3 (x ((y (z)))) (4 5 ((((((:xxx)))))))) 0) 
[(:xxx) 7] 

user> (deepest '(1 2 3 ((((((((nil)))))))) (x ((y (z)))) (4 5) 6) 0) 
[(nil) 8] 

user> (deepest '(1 2 3) 0) 
[(1 2 3) 0] 
関連する問題