Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Clojure中获取树的密钥链_Clojure - Fatal编程技术网

在Clojure中获取树的密钥链

在Clojure中获取树的密钥链,clojure,Clojure,我想得到一棵树的钥匙链,从每一根到每一片叶子 例如,输入树: {"b" {:term true}, "a" {"y" {:term true}, "x" {:term true}}} 我期望的结果是: (("b" :term) ("a" "x" :term) ("a" "y" :term)) or ["b" "ax" "ay"] 我找到了一个尾部递归,它工作得很好: (defn down-strings [trie] "this one works. 80msecs for addre

我想得到一棵树的钥匙链,从每一根到每一片叶子

例如,输入树:

{"b" {:term true}, "a" {"y" {:term true}, "x" {:term true}}}
我期望的结果是:

(("b" :term) ("a" "x" :term) ("a" "y" :term)) or ["b" "ax" "ay"]
我找到了一个尾部递归,它工作得很好:

(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)))))))))
现在我的递归实践遇到了问题:

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

(("b" [:term]) ("a" ("y" [:term]) ("x" [:term])))
我尽了我所能,但没能解决这个问题

(defn down-strings
  ([trie] (down-strings trie []))
  ([trie prefix]
     (if (map? trie)
       (mapcat (fn [[k v]]
                 (down-strings v (conj prefix k)))
               trie)
       [prefix])))
递归解决方案更容易,使用一个额外的参数表示每个分支的累积状态,并且使用
mapcat
确保每个路径都是一个序列,而不是序列的深度嵌套(路径中每个项的嵌套级别更高)。 `

比如说,

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

我预计这会比以前慢一点

#(让[[dk dv]][(clojure.string/join[k dk])dv])
写得更好,因为它与相同的
(fn[[dk dv]][(str k dv)dv])
非常感谢。终于开始懂得如何递归思考了。如果您想要一个展平列表作为最终结果,那么每个迭代结束时的内部结果至少应该是一个展平列表!这就是我用“地图”失败的原因。再次感谢@Thumbnail!后来我发现每次“地图”把我弄得乱七八糟,“地图猫”就来救我。我应该更多地关注Clojure的seq。@Choulin确实关注解决方案。有很多技巧在展示。
(down-strings {"b" {:term true}, "a" {"y" {:term true}, "x" {:term true}}})
;("ax" "ay" "b")