最小/最大和列表中最常见的元素

时间:2015-11-04 18:59:54

标签: f#

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

FindFeature(cv::Mat_<Vec3b>& image) 
{
    image.forEach<Vec3b>([](Vec3b &p, const int * position) -> void 
    { p[0] /= 2; p[1] /= 2; p[2] /= 2;});
}

FindFeature(cv::Mat_<uchar>& image) 
{
    image.forEach<uchar>([](uchar &p, const int * position) -> void 
    { p /= 2; });
}

template<typename Pixel>
void FindFeature(cv::Mat_<Pixel>& image)
{
     // we don't know how to work on any other image type
     throw std::runtime_exception("unsupported image type");
}

void main()
{
    int flags = CV_LOAD_IMAGE_COLOR | CV_LOAD_IMAGE_ANYDEPTH
    cv::Mat image = imread("c:\image.jpg", flags);
    Dispatch(FindFeature, image);
}

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

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

3 个答案:

答案 0 :(得分:4)

我将从@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

答案 1 :(得分: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

答案 2 :(得分:0)

不使用标准模块的选项:

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

关于第二个问题 - 表明他们试图解决。