Clojure地图转换(儿童对树中的父亲)

时间:2013-02-22 17:42:02

标签: clojure

假设我在树中有以下节点映射及其子节点:

(def a {0 [], 1 [], 2 [0, 1]})

对应于其根节点 2 的树和两个叶节点 0 1 作为节点 2 孩子们。

如何将其转换为父亲的地图,或者更好的是,与父亲一起装饰它。例如。到达下面的父亲地图:

{0 2, 1 2, 2 nil} ; each node only has one father at most

或者,更好的是,在下面的地图中结合了儿童和父亲:

{0 [[] 2], 1 [[] 2], 2 [[0,1] nil]}

2 个答案:

答案 0 :(得分:4)

第一位:

(def a {0 [], 1 [], 2 [0, 1]})

(defn parent-map [m]
  (reduce 
    (fn [x [k v]] 
      (into x (zipmap v (repeat k)))) {} m))

(def parent (parent-map a))   

parent 
=> {1 2, 0 2}
(parent 1)
=> 2 
(parent 2)
=> nil

因此,无需在父地图中明确显示2 nil

第二位:

(defn parent-child-map [m]
  (let [parent (parent-map m)]
    (reduce 
      (fn [x [k v]] 
        (assoc x k [(m k) (parent k)])) {} m)))

(parent-child-map a)
=> {2 [[0 1] nil], 1 [[] 2], 0 [[] 2]}

更有趣的事情:

(def b {0 [], 1 [], 2 [], 3 [], 4 [0 1 2], 5 [3], 6 [4 5]})

(parent-child-map b)
=>
{6 [[4 5] nil],
 5 [[3] 6],
 4 [[0 1 2] 6],
 3 [[] 5],
 2 [[] 4],
 1 [[] 4],
 0 [[] 4]}

答案 1 :(得分:2)

(defn parents [m]
  (let [plist (into {} (for [[k v] m vv v] [vv k]))]
    (into {} (map (fn [[k v]] [k [v (plist k)]]) m))))

(parents a)
=> {0 [[] 2], 1 [[] 2], 2 [[0 1] nil]}