如何将列表的平均值与同一列表中的每个元素进行比较?

时间:2019-03-01 05:31:45

标签: functional-programming sml

fun promedio l = let
    fun sl(nil, sum, len) = sum div len
    |  sl(h::t, sum, len) = sl(t, sum + h, len + 1)
in 
 sl(l, 0, 0)
end;

此代码为我提供了列表的平均值,但是现在我必须将列表中的每个元素与平均值进行比较,并说出有多少个元素大于平均值,有多少个元素小于平均值。

您能否在最后一步帮助我?

1 个答案:

答案 0 :(得分:0)

您的promedio函数在空输入时失败; promedio [],因为它试图除以零。

这里有两种方法可以将空列表考虑在内:

(* Using one traversal *)
fun average xs =
    case foldl (fn (x, (sum, count)) => (x + sum, 1 + count)) (0, 0) xs of
         (0, 0) => 0
       | (x, y) => x div y

(* Using two traversals *)
val sum = foldl op+ 0
fun average [] = 0
  | average xs = (sum xs) div (length xs)

您可以使用带有List.partition的任何谓词对列表进行分区

在您的情况下,谓词可能是x <= avg

fun partition_average xs =
    let val avg = average xs
    in List.partition (fn x => x <= avg) xs end

请注意,如果我没有将average xs之外的avg绑定到fn x => ...

(* Don't do this *)
fun partition_average xs =
    List.partition (fn x => x <= average xs) xs

然后我将为average xs的每个元素重新计算xs

演示:

- partition_average [1,2,3,4,5]; (* avg being 3 *)
> val it = ([1, 2, 3], [4, 5]) : int list * int list

- partition_average [1,2,3,9]; (* avg being 3(.75) *)
> val it = ([1, 2, 3], [9]) : int list * int list