2011-12-11 16 views
5

Voglio trovare il massimo, il minimo e la media in un array senza .NET in F #. Ho usato questo codice ma non funziona:Trova il massimo, il minimo e la media in 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 
+2

uso Array.max, Array.min, Array.averageBy float – BLUEPIXY

risposta

1

ho fissato il codice per max

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 

Per trovare max, min e avg, con il suo approccio:

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) 

ma nota che si può fare solo :

let max = Seq.max arrX 
let min = Seq.min arrX 
let avg = Seq.averageBy float arrX 
0

ci sono alcuni problema logico per calcolare max qui. E il posizionamento di printfn verrà stampato al massimo ogni volta che cambia. Il seguente codice funziona:

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 
+0

Grazie mille – Massoud

7

Mentre le risposte già pubblicate sono p validamente valido per il motivo per cui il codice postato non funziona, direi che l'utilizzo di un loop e una variabile mutabile non è molto ... funzionale. Così ho pensato di postare un altro modo di fare # F - idiomatico per risolverlo.

Si dichiara "impossibile utilizzare .NET". Sto indovinando vuoi dire che non è possibile utilizzare alcuna delle funzioni integrate o librerie .NET. Ovviamente, questo significa anche che tu puoi implementarli da soli utilizzando primitive F #.

Una funzione comune nel mondo funzionale è fold, che applica semplicemente una funzione a tutti gli elementi di una sequenza, mantenendo il ritorno di tale funzione in un accumulatore. La versione built-in è Seq.fold, ma dal momento che non possiamo usare che, definiremo uno di noi:

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

Questa è una funzione ricorsiva che applica la funzione accFn ad ogni elemento, e poi si fa chiamare con il resto dell'array. Quando viene passato un array vuoto, la ricorsione termina.

Quando si ha che, definiamo alcune semplici funzioni di passare nel 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 

volta abbiamo che la soluzione al problema dichiarato è semplice:

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

Grazie mille – Massoud

0
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

diArray è come ridurre – BLUEPIXY

Problemi correlati