【问题标题】:How to find the minimum element in a Map and return a tuple (key,minimum element)?如何在 Map 中找到最小元素并返回一个元组(键,最小元素)?
【发布时间】:2020-04-20 07:04:16
【问题描述】:

我有这些类型:

type position = float * float
type node = position

我已经编写了这些模块来创建我的地图:

module MyMap =
  struct
  type t = node
  let compare (a1,b1) (a2,b2) =
    if a1 > a2 then 1
     else if a1 < a2 then -1
     else if b1 > b2 then 1
       else if b1 < b2 then -1

       else 0
  end

module DistMap = Map.Make(MyMap)

我尝试编写使用iter 的函数,但尝试以正确的语法表达我的想法没有成功。

我的目标是能够拥有一个以 Map 作为参数并返回最小元素及其键的元组的函数。

谢谢。

【问题讨论】:

    标签: dictionary ocaml minimum


    【解决方案1】:

    如果您要求最小键及其对应元素,这很简单:使用DistMap.min_binding_opt,如果您可以在空地图上引发异常,请使用DistMap.min_binding

    如果您要求最小元素及其对应的键,您将需要使用折叠。幸运的是,Map.Make 返回的DistMap 模块公开了一个fold 函数,因此您不必进行额外的分配,例如调用to_seq 并对结果进行折叠。此外,由于地图中元素的类型不受仿函数应用程序的限制(即,您可以创建具有任何元素类型的地图),因此您需要客户端提供元素类型的比较函数。

    DistMap.fold 的类型为(key -&gt; 'a -&gt; 'b -&gt; 'b) -&gt; 'a t -&gt; 'b -&gt; 'b,因此我们必须实例化'b,以便同时跟踪 key 和 min 元素;换句话说,我们将'a 实例化为地图的元素类型(我们称之为t),并将'b 实例化为(key * t) option(其中key = position = float * float)。

    代码如下所示:

    let min_element_and_its_key map ~compare_element =
      let take_min key element key_and_min_element =
        match key_and_min_element with
        | None -> Some (key, element)
        | Some (key_for_min_element, min_element) ->
          if compare_element element min_element < 0
          then Some (key, element)
          else Some (key_for_min_element, min_element)
      in
      DistMap.fold take_min map None
    

    min_element_and_its_key 将在空地图上返回 None

    示例客户端代码(您可以在 ocaml repl 中运行)可能如下所示:

    let map = DistMap.(empty |> add (3., 3.) "a" |> add (4., 4.) "b") in
    min_element_and_its_key map ~compare_element:String.compare;;
    
    (* Output: *)
    - : (node * string) option = Some ((3., 3.), "a")
    

    一般来说,只要你想遍历数据结构中的所有键/元素并累积一个值,fold 就是要走的路。 iter 会起作用,但是您必须在可变状态下累积值,而不是直接将其累积为要折叠的函数的返回值。

    【讨论】:

    • 测试有语法错误是否正常?错误在in
    • 我给你的测试是表达式,不是顶层声明。要将其作为声明包含在您的文件中,您可以编写:let () = (* and then the same expression as before *).
    猜你喜欢
    • 1970-01-01
    • 2022-11-27
    • 2020-02-10
    • 2014-07-21
    • 2014-11-08
    • 2014-05-07
    • 2018-11-29
    • 2011-06-14
    • 2012-11-13
    相关资源
    最近更新 更多