get key-chains of a tree in Clojure [duplicate]

一曲冷凌霜 提交于 2020-01-06 11:48:55

问题


I wanted to get key-chains of a tree, from every root to every leave.

for example input tree:

{"b" {:term true}, "a" {"y" {:term true}, "x" {:term true}}}

I was expecting output:

(("b" :term) ("a" "x" :term) ("a" "y" :term)) or ["b" "ax" "ay"]

I've figured out a tail-recursion, it worked fine:

(defn down-strings [trie] 
  "this one works. 80msecs for address.txt, not bad at all"
  (lazy-seq 
    (loop [strings [],trie trie] 
      (if (empty? trie) strings
        (let [[k v] (first trie)] 
          (recur (if (:term v) (conj strings k) strings)
                 (reduce 
                   conj 
                   (rest trie)
                   (map (fn [[dk dv]] [(str k dk) dv]) (dissoc v :term)))))))))

Now I have trouble with my recursive practice:

(defn down-strings [trie]
  (if (map? trie)
      (map (fn [[k v]] (conj (down-strings v) k)) trie)
      []))

the output is :

(("b" [:term]) ("a" ("y" [:term]) ("x" [:term])))

I tried everything I could, couldn't fix this.


回答1:


(defn down-strings [trie]
  (mapcat
    (fn [[k v]]
      (if (map? v) (map (partial str k) (down-strings v)) [""]))
    trie))

For example,

(down-strings {"b" {:term true}, "a" {"y" {:term true}, "x" {:term true}}})
;("ax" "ay" "b")

I expect this to be quite a bit slower than @noisesmith's solution.




回答2:


(defn down-strings
  ([trie] (down-strings trie []))
  ([trie prefix]
     (if (map? trie)
       (mapcat (fn [[k v]]
                 (down-strings v (conj prefix k)))
               trie)
       [prefix])))

A recursive solution is easier with an extra argument representing the accumulated state of each branch taken, and the usage of mapcat ensures that each path is one sequence, instead of deep nesting of sequences (an extra level of nesting per term in the path). `



来源:https://stackoverflow.com/questions/25268818/get-key-chains-of-a-tree-in-clojure

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!