2017-01-26 73 views
2

我试图在未使用List.Max的情况下在使用下面给定的模板的学校作业中找到列表中的最大元素。使用模式匹配和递归在列表中查找最大元素F#

 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];;  

有什么办法,我可以从我建一个使用模板功能去?谢谢!

+2

可能的重复[我如何从列表中获取最大值与函数,需要两个参数?](http://stackoverflow.com/questions/13474382/how-do-i-get-the-max - 值 - 从 - 一个列表上带有一个功能 - 即通吃两个参数) –

回答

4

您的辅助函数应该做的工作,外部函数只是验证该列表不为空,如果它不是,来电助手,它应该是这样的:

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

注意,你因为你对函数的最后一个参数匹配,你可以将其删除,并使用function代替matchwith

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

你可以去一个元组通过这两个,或简单地套用辅助函数我ñ你的主要匹配(而不是空列表守卫子句)。我为将来可能会发现这个问题的人提供了答案,并且没有明确的答案。

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
let findMax l = 
    let rec helper(l,m) = 
    match l with 
    | [] -> m 
    | (x::xs) -> helper(xs, if (Some x > m) then Some x else m) 
    helper (l,None) 

实施例:

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

列表为空时返回None。

0

我不确定你的assigment的确切规则是什么,但列表的最大值只是List.reduce max。所以

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

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

let inline listMax xs = List.reduce max xs 

也可以工作并且是通用的,所以它可以与例如浮动和字符串以及。