问题
I have to write a program which give in output a tuple with: min and max of a not-empty list and the value that appears most often. In particular:
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
This is the code that I wrote for max (min is almost equal) but how can I do to receive as output a tuple with the two values?
let rec max_list xs =
match xs with
| [] -> failwith "xs" "Empty list"
| [x] -> x
| x1::x2::xs' -> max_list((max2 x1 x2)::xs');;
回答1:
I'll take the first suggestion from @Mark Seemann's answer and run with it, in order to make it generic, working with any collection type, and handle the case of the empty collection sensibly.
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)
For the most frequent part of the question:
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)
Not particularly efficient, but fun to write:
let mode xs =
xs
|> List.groupBy id
|> List.map (fun (i, is) -> i, Seq.length is)
|> List.maxBy snd
|> fst
回答3:
Option without the use of standard modules:
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
On the second question - show their attempts to solve.
来源:https://stackoverflow.com/questions/33529942/min-max-and-most-frequent-element-of-a-list