【问题标题】:How can I change the type of the tree to return the correct value for almost any kind of tree?如何更改树的类型以返回几乎任何类型的树的正确值?
【发布时间】:2019-11-20 02:48:05
【问题描述】:

我正在尝试查找节点树的最大值,但我遇到了这种错误 此表达式的类型为 int bintree,但表达式应为 'a bintree bintree 类型。 int 类型与 'a bintree 类型不兼容。

type 'a bintree =
| Nil
| T of 'a bintree * 'a * 'a bintree ;;

let t = T (T (T (Nil, 1, Nil), 2, T (Nil, 3, Nil)), 4, T (T (Nil, 6, Nil), 5, Nil)) ;;

let rec maximum t = 
  match t with
  |Nil -> Nil
  | T (Nil, v, Nil) -> v
  | T (l, v, r) -> max (maximum l) (maximum r) ;;

【问题讨论】:

    标签: ocaml


    【解决方案1】:

    您的问题是确定空树的最大值。最大值应该是 'a 类型,但您返回的是 Nil,它是 'a bintree 类型。

    这实际上是一个有趣的问题。您需要一个适用于任何类型的值。但是真的没有这样的价值。

    一种可能性是有一个额外的参数来指定当树为空时要使用的值。对于树中的任何类型,它将表示负无穷大(可能的最小值)。

    另一个(可能更好的)解决方案,正如@ThéoWinterhalter 所建议的,是让你的函数返回类型为'a option。当树为空时它将返回None,否则返回Some maxval

    【讨论】:

    • 不正确的方法是使用option吗?与maximum Nil = None.
    • 是的,我正要将此添加到我的答案中。谢谢!
    • 你的最后一个分支不也需要考虑 v 吗?
    • 如果你有一个有值的右分支,你能忽略左分支吗?抱歉,我在考虑排序树。
    • 这是尝试在各种容器上定义“最大”或“最小”函数时的常见问题。除了已经提到的方法之外,另一种方法是确保容器具有至少一个元素。 1. 从树中提取一个值或调用invalid_arg "empty tree" 2. 将该值用作初始最佳候选值,这样您就不必处理选项类型。
    【解决方案2】:

    在扫描项目集合以查找某种最佳元素(例如最大值或最小值)时,这是一个常见问题。问题是容器可能是空的,在这种情况下,无法提取“最佳元素”。 OCaml 提供了option 类型来表示值或不存在值,因此在这里使用它是一个好主意。这就是我的解决方案的样子:

    let maximum t =
      let rec loop best t =
        match t with
        | Nil -> best
        | T (l, v, r) ->
          let best = max best v in
          let best = max best (loop best l) in
          loop best r
      in
      match t with
      | Nil -> None
      | T (_, init, _) -> Some (loop init t)
    

    如果树为空,即它是Nil,则返回None。否则返回Some v,其中v 是集合的最佳元素,即由max 函数确定的最大值。

    这种技术依赖于首先从容器中提取一个元素。这是我们最初的候选人。然后我们继续扫描容器寻找更好的候选人,最后返回我们找到的最佳候选人。同样的技术可以适用于列表、数组和其他容器。也可以对其进行参数化,以便将“二选一”函数作为参数,例如min,如果我们想获得最小值而不是最大值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-09-30
      • 1970-01-01
      • 2012-02-21
      • 2018-01-29
      • 1970-01-01
      • 2015-08-07
      相关资源
      最近更新 更多