Найти максимум, минимум и среднее в F # - PullRequest
5 голосов
/ 11 декабря 2011

Я хочу найти максимум, минимум и среднее в массиве без .NET в F #. Я использовал этот код, но он не работает:

let mutable max = 0
let arrX = [|9; 11; 3; 4; 5; 6; 7; 8|]

for i in 0 .. arrX.Length - 2 do
  if (arrX.[i]) < (arrX.[i+1]) then 
       max <- arrX.[i]
       printfn "%i" max

Ответы [ 4 ]

8 голосов
/ 11 декабря 2011

Несмотря на то, что уже опубликованные ответы совершенно верны в отношении того, почему ваш опубликованный код не работает, я бы сказал, что использование цикла и изменяемой переменной не очень ... функционал .Поэтому я подумал, что опубликую более идиоматический способ ее решения на F #.

Вы утверждаете, что «не можете использовать .NET».Я предполагаю, что вы имеете в виду, что вы не можете использовать любые встроенные функции или библиотеки .NET.Конечно, это также означает, что вы можете реализовать их самостоятельно, используя примитивы F #.

Одной из распространенных функций в функциональном мире является fold, которая просто применяет функцию ко всем элементампоследовательность, сохраняя возврат этой функции в аккумуляторе.Встроенная версия - Seq.fold, но поскольку мы не можем ее использовать, мы определим ее сами:

let rec fold accFn arr acc = 
    match arr with
    | [||] -> acc
    | _ -> fold accFn arr.[1..] (accFn arr.[0] acc)

Это рекурсивная функция, которая применяет функцию accFn к каждому элементу.и затем вызывает себя с остатком массива.Когда ему передают пустой массив, рекурсия завершается.

Когда у нас это есть, давайте определим некоторые простые функции для передачи в fold:

let min x y =
    if x < y then x 
    else y

let max x y = 
    if x > y then x
    else y

let sum x y = 
    x + y

Как только мы это получим, решениек заявленной проблеме просто:

let arrX= [|9; 11; 3; 4; 5; 6; 7; 8|]
let head = arrX.[0]
let avg = (fold sum arrX 0) / arrX.Length
let minValue = fold min arrX head
let maxValue = fold max arrX head
1 голос
/ 11 декабря 2011

Я исправил твой код для макс.

let mutable max = 0
let arrX= [|9; 11; 3; 4; 5; 6; 7; 8|]

for i in 0 .. arrX.Length - 1 do
  if max < (arrX.[i]) then 
       max <- arrX.[i]
       printfn "%i" max

Чтобы найти максимальные, минимальные и средние значения, используя ваш подход:

let mutable max = System.Int32.MinValue
let mutable min = System.Int32.MaxValue
let mutable sum = 0
let arrX= [|9; 11; 3; 4; 5; 6; 7; 8|]

for i in 0 .. arrX.Length - 1 do
  if max < (arrX.[i]) then 
       max <- arrX.[i]
       printfn "max %i" max
  if min > (arrX.[i]) then 
       min <- arrX.[i]
       printfn "min %i" min
  sum <- sum + arrX.[i]
printfn "-> max is %i" max
printfn "-> min is %i" min
printfn "-> avg is %f" (float sum / float arrX.Length)

Но обратите внимание, вы можете сделать только:

let max = Seq.max arrX
let min = Seq.min arrX
let avg = Seq.averageBy float arrX
0 голосов
/ 11 декабря 2011
let ofArray f (a : 'T array) =
  let len = a.Length
  let rec aux index ret =
    if index >= len then
      ret
    else
      aux (index+1) (f a.[index] ret)
  aux 1 a.[0]

let maxOfArray (a : 'T array) = ofArray max a
let minOfArray (a : 'T array) = ofArray min a
let inline sumOfArray (a : 'T array) = ofArray (+) a

let main() =
  printfn "max: %d" <| maxOfArray arrX
  printfn "min: %d" <| minOfArray arrX
  printfn "ave: %f" <| (sumOfArray arrX |> float) / (arrX.Length |> float)

do main() 
0 голосов
/ 11 декабря 2011

Здесь есть логическая проблема для вычисления max. И размещение printfn будет печатать максимум при каждом изменении. Работает следующий код:

let mutable max = 0
let arrX= [|9; 11; 3; 4; 5; 6; 7; 8|]

for i in 0 .. arrX.Length-1 do
    if max < arrX.[i] then 
        max <- arrX.[i]
printfn "%i" max
...