簡體   English   中英

F#數組和匹配模式

[英]F# arrays and match pattern

我正在嘗試使用遞歸學習F#和數組。 我已經解決了用遞歸概括數組的問題,除了這次我使用匹配模式,我試圖做同樣的事情,但是我無法得到它的幫助。

let myArray = Array.create 5 0

myArray.[0] <- 0
myArray.[1] <- 1
myArray.[2] <- 2
myArray.[3] <- 3
myArray.[4] <- 4

let rec sum (arr : int array) counter =
    if counter = 0 then 0
    else arr.[counter] + sum arr (counter - 1)

////////////////////////////////////////////////
// Can't get this to work.

let rec sum1 (arr : int array) counter =
    match arr with
    | [||] -> printfn "0"
    | arr -> arr.[counter] + sum arr (counter - 1)  

實現的問題是,您希望不可變的arr從call更改為sum1 它不會改變,因此您的實現可以執行任何操作,但是當counter變為負數時,空數組將引發System.IndexOutOfRangeException

繼續堅持使用索引進行操作:

let rec sum1 (arr : int array) counter =
    match counter with
    | 0 -> 0
    | _ -> arr.[counter - 1] + sum1 arr (counter - 1)

並且sum1 myarray (myarray.Length)返回預期的10

該實現不如您使用if-then-else第一個sum完美。 要理解為什么只是嘗試使用let myarray = Array.init 100000 id類的東西運行它-它可能會拋出System.Stackoverflow異常。 導致異常的原因-它不是尾遞歸的

使它成為尾遞歸並不困難-只需添加一個累加器sum完全取消后續調用的堆棧:

let rec sum1TR sum counter (arr: int[]) =
    match counter with
    | 0 -> sum
    | _ -> sum1TR (sum + arr.[counter - 1]) (counter - 1) arr

現在sum1TR 0 1000000 (Array.init 1000000 id)甚至可以用於一百萬個項目的數組。

最后,你想數組元素的總和是有意義的暴露到最終用戶只有一個參數-本身的陣列,移動遞歸summator外部函數中:

let sum (as: int[]) =
    let rec summator s l =
        match l with
        | 0 -> s
        | _ -> summator (s + as.[l - 1]) (l - 1)
    summator 0 as.Length

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM