计算整数列表的模式?

Mor*_*oth 4 f# average

是否有内置函数来计算F#中的整数列表的模式?

如果我有一个整数列表,如下:

let integers = [1; 2; 3; 4; 5; 3]
Run Code Online (Sandbox Code Playgroud)

我希望结果如此3.

Fyo*_*kin 6

不,没有这样的内置功能.这是一个天真的实现:

let mode = function
    | [] -> None
    | xs -> 
        let mostFrequentTwo =
            xs
            |> Seq.groupBy id 
            |> Seq.map (fun (n, ns) -> n, Seq.length ns)
            |> Seq.sortByDescending snd
            |> Seq.truncate 2
            |> Seq.toList

        match mostFrequentTwo with
        | [(x, xSize); (_, ySize)] when xSize > ySize -> Some x
        | [(x, _)] -> Some x
        | _ -> None
Run Code Online (Sandbox Code Playgroud)

首先,它对列表中的数字进行分组,然后获取每个组的大小,然后按照大小按降序对组进行排序,然后选择前两个.如果有两个组并且第一个组较大,那么这就是模式; 如果只有一个组,那么它就是模式; 否则没有模式.

我把这个实现称为"天真",因为它做了一些严格说来不必要的事情:一个更好的方法是首先对数字进行排序,然后仔细查看前两个组,并比较它们的大小.然而,编写起来会更复杂并且难以理解,但上述解决方案的计算复杂性仍然n * log n(甚至是线性的,取决于分组和排序实现),因此在看到性能之前似乎没有必要进行优化数据.

  • 请注意,有一个`Seq.countBy`,相当于你的`Seq.groupBy id >> Seq.map(...)`. (3认同)