使用模式匹配和递归F#查找列表中的最大元素

时间:2017-01-26 00:39:03

标签: f# f#-3.0

我尝试使用下面给出的模板在不使用List.Max进行学校作业的情况下查找列表中的最大元素。

        let findMax l = 
        let rec helper(l,m) = failwith "Not implemented"

        match l with
        | [] -> failwith "Error -- empty list"
        | (x::xs) -> helper(xs,x) 

我能想到的唯一解决问题的方法是atm

        let rec max_value1 l =
          match l with
          |[] -> failwith "Empty List"
          |[x] -> x
          |(x::y::xs) ->  if x<y then max_value1 (y::xs)
                else max_value1 (x::xs)

        max_value1 [1; 17; 3; 6; 1; 8; 3; 11; 6; 5; 9];;    

有什么方法可以从我构建的函数转到使用模板的函数吗?谢谢!

4 个答案:

答案 0 :(得分:5)

你的帮助函数应该做的工作,外部函数只是验证列表不是空的,如果不是,调用帮助器,这应该是这样的:

let rec helper (l,m) = 
    match (l, m) with
    | []   , m -> m
    | x::xs, m -> helper (xs, max m x)

请注意,自从您与该函数的最后一个参数匹配后,您可以将其删除并使用function代替match with

let rec helper = function
    | []   , m -> m
    | x::xs, m -> helper (xs, max m x)

答案 1 :(得分:4)

[-2;-6;-1;-9;-56;-3] |> findMax  
val it : int option = Some -1

示例:

"Out of memory"

空列表将返回None。

答案 2 :(得分:2)

您可以使用元组来传递两者,或者只是在主匹配中应用辅助函数(而不是空列表保护子句)。我为将来可能会发现这个问题并且没有明确答案的人提供答案。

let findMax l = 
   let rec walk maxValue = function
       | [] -> maxValue
       | (x::xs) -> walk (if x > maxValue then x else maxValue) xs
   match l with 
   | [] -> failwith "Empty list"
   | (head::tail) -> walk head tail

findMax [1; 12; 3; ] //12

使用折叠:

let findMax l = l |> List.fold (fun maxValue x -> if x > maxValue then x else maxValue) (List.head l)

答案 3 :(得分:1)

我不确定您的分配的确切规则是什么,但列表的最大值实际上只是libperipheralman.so。所以

List.reduce max

你需要类型注释来取悦typechecker。

let listMax : int list -> int = List.reduce max

也有效并且是通用的,所以它适用于例如漂浮物和弦乐。