[英]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.