Как я могу сравнить среднее значение списка с каждым элементом в том же списке? - PullRequest
0 голосов
/ 01 марта 2019
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 голосов
/ 05 марта 2019

Ваша функция 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
...