【问题标题】:Min/Max and most frequent element of a list列表的最小/最大和最频繁的元素
【发布时间】:2015-11-04 18:59:54
【问题描述】:

我必须编写一个程序,在输出中给出一个元组:非空列表的最小值和最大值以及最常出现的值。 特别是:

min_max [1;0;-1;2;0;-4] ==> (-4; 2)
min_max: int list -> (int * int)

mode [-1;2;1;2;5;-1;5;5;2] ==> 2
mode: int list -> int

这是我为 max 编写的代码(min 几乎相等),但是如何接收具有两个值的元组作为输出?

let rec max_list xs =
    match xs with
    | [] -> failwith "xs" "Empty list"
    | [x] -> x
    | x1::x2::xs' -> max_list((max2 x1 x2)::xs');;

【问题讨论】:

  • 作为旁注;你的max_list 的目的似乎有点复杂;如果当前头部更大,则可以更简单地使用列表的其余部分传递当前最大值并更新它。或不传递它;只返回当前头部和尾部的 max_list 之间的最大值

标签: f#


【解决方案1】:

我将从@Mark Seemann 的回答中获取第一个建议并运行它,以使其通用,适用于任何集合类型,并明智地处理空集合的情况。

let tryMinMax xs =
    Seq.fold (function
    | Some(mn, mx) -> fun i -> Some(min mn i, max mx i)
    | None         -> fun i -> Some(i, i) ) None xs

[1;0;-1;2;0;-4]
|> tryMinMax
// val it : (int * int) option = Some (-4, 2)

对于问题中最常见的部分:

let mostFrequent xs =
    xs 
    |> Seq.countBy id 
    |> Seq.maxBy snd
    |> fst

[1;0;-1;2;0;-4]
|> mostFrequent
// val it : int = 0

【讨论】:

    【解决方案2】:
    let minMax xs =
        xs
        |> List.fold
            (fun (mn, mx) i -> min mn i, max mx i)
            (System.Int32.MaxValue, System.Int32.MinValue)
    

    效率不是特别高,但写起来很有趣:

    let mode xs =
        xs
        |> List.groupBy id
        |> List.map (fun (i, is) -> i, Seq.length is)
        |> List.maxBy snd
        |> fst
    

    【讨论】:

    • 为什么不立即使用 maxBy ,而不使用地图? (List.maxBy(fun (_,x) -> Seq.length x))
    • @FoggyFinder 没有特别的原因:)
    • 因为我不能使用教授解释之外的任何功能:这是我必须做练习时的问题,因为在这种情况下我也立即想到了 lis.map , list.fold, seq.fold 等
    • @SimoneCalliari 通常,练习是从递归实现转到使用折叠,但您也应该能够采用另一种方式。
    【解决方案3】:

    不使用标准模块的选项:

    open System
    let tryMinMax xs = 
        let rec minMax xs mn mx = 
            match xs with | [] -> mn, mx | h::t -> minMax t (min mn h) (max mx h)
        match xs with | [] -> None | _ -> Some(minMax xs Int32.MaxValue Int32.MinValue)
    

    dotnetfiddle

    关于第二个问题 - 展示他们解决的尝试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-31
      • 1970-01-01
      • 1970-01-01
      • 2013-12-15
      相关资源
      最近更新 更多