我希望得到一棵树的钥匙链,从每个根到每一个假。
例如输入树:
{"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])))
我尽我所能,无法解决这个问题。
答案 0 :(得分:1)
(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
的使用确保每个路径是一个序列,而不是序列的深层嵌套(额外的嵌套级别)每个学期的路径)。
`
答案 1 :(得分:1)
(defn down-strings [trie]
(mapcat
(fn [[k v]]
(if (map? v) (map (partial str k) (down-strings v)) [""]))
trie))
例如,
(down-strings {"b" {:term true}, "a" {"y" {:term true}, "x" {:term true}}})
;("ax" "ay" "b")
我希望这比@noisesmith's solution慢一点。