2014-01-09 65 views
0

我在试着学习F#和递归数组。我已经解决了递归总结一个数组现在我试图做同样的事情,除了这次匹配模式,但我不能得到它的工作帮助。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) 
+1

是不是'sum1'应该是递归的?你的意思是从'sum1'中调用'sum'? –

回答

4

与实现的问题是,你希望一成不变arr某种方式从更换呼叫来电sum1。它不会改变,所以你的实现任何东西,但空数组将抛出System.IndexOutOfRangeExceptioncounter变负!

继续坚持操作与索引:

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

而且sum1 myarray (myarray.Length)回报10预期。

这个实现并不完美,您的第一个sumif-then-else也不完美。要理解为什么试着用let myarray = Array.init 100000 id这样的东西来运行它 - 它可能会抛出System.Stackoverflow异常。例外原因 - 它不是tail-recursive

使其成为尾递归并不难 - 只需添加一个累加器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