【问题标题】:Traverse a multiway tree遍历多路树
【发布时间】:2022-01-05 06:32:23
【问题描述】:

我正在尝试遍历多路树,并像 List.map 那样映射它的值。

这是我的尝试

type 'a tree = Node of 'a * ('a tree list);;

let tree_map f t = 
  let rec aux acc tr =
    match tr with
    | Node(v, []) -> Node(f v, []) :: acc
    | Node(v, sub) -> let r = List.fold_left aux acc sub in Node(f v, r) :: acc
  in aux [] t
;;

let t = Node (1, [Node (2, [Node (1, [])]); 
                  Node (3, []);
                  Node (1, [Node (5, []); 
                            Node (2, [])])]);;
;;

let res = tree_map (succ) t;;

我尝试了来自this 答案的建议。未能成功实施。

我的函数返回这个显然是不正确的

val res : int tree list =
  [Node (2,
    [Node (2,
      [Node (3, []); Node (6, []); Node (4, []); Node (3, [Node (2, [])])]);
     Node (4, []); Node (3, [Node (2, [])])])]

有什么问题?

【问题讨论】:

    标签: ocaml


    【解决方案1】:

    参加聚会有点晚了,但既然我已经完成了这项工作并向您展示了该功能可以简化多少:

    let rec tree_map f (Node (v, sub)) =
      Node(f v, List.map (tree_map f) sub)
    

    【讨论】:

      【解决方案2】:

      您所指的答案是关于折叠迭代器,即当您将某些函数应用于树的每个节点以构建某些值时。 map 迭代器有点不同,而且更容易实现。对于每个节点,您应返回映射的节点。

      请务必记住,map 迭代器应保留数据的结构,例如,当您拥有叶节点时,您需要返回映射的叶节点,例如,

      | Node (v, []) -> Node (f v, []) 
      

      一般情况也是如此,即,您需要使用 map 迭代器,而不是使用折叠迭代器,例如,

      | Node(v, sub) -> Node (f v, List.map (aux f) sub)
      

      事实上,您甚至不需要空节点案例,因为一般案例适用于所有节点。这将使您tree_map 成为一个微不足道的单行:)

      并且不要忘记从aux 中删除acc 参数,你不需要它。

      【讨论】:

      • 即使这样:Node(v, sub) -> Node (f v, List.map (aux f) sub) 似乎与不必要的 aux 过于复杂。请参阅@glennsl 的回答。
      • 当然,但不要忘记 SO 的教学目的。挑战不是用最漂亮的代码给出最短的答案,而是教如何做到这一点!
      【解决方案3】:

      我看到的一个问题是,您只是在使用 List.fold_left 的结果。但是左折叠会返回一个反向列表。

      # List.fold_left (fun acc n -> (n + 1) :: acc) [] [1;2;3];;
      - : int list = [4; 3; 2]
      

      第二个问题是你在同一个表达式的两个地方使用了acc

      let r = List.fold_left aux acc sub in Node(f v, r) :: acc
      

      这将复制树的一部分。在我看来,其中一个地方应该使用[] 而不是acc

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-25
        • 1970-01-01
        • 2020-12-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多