2014-05-06 179 views
2

使用F#,我想计算没有任何循环的数组的累积乘积。第一个想法是使用Array.fold和Array.map,但我不明白我可以如何使用它们。你有什么建议?或使用递归函数peharps?非常感谢您的帮助。F#数组的累积积

回答

4

如果你需要的所有元素的产品,你可以使用折叠确实:

> let a = [|1;2;3;4;5|]; 
> a |> Array.fold (*) 1;; 

val it : int = 120 

如果需要中间(累计)的结果,你可以使用scan。扫描获取数组中的每个元素并将一个函数(本例中为product)应用于该元素以及之前的累计结果。与蓄能值1开始,我们得到:

> a |> Array.scan (*) 1;; 

val it : int [] = [|1; 1; 2; 6; 24; 120|] 
+0

当然,你也可以用'fold'(或'unfold',列表和序列!)来实现你自己的'scan'。 – Mau

+2

我完全忘记了扫描。非常感谢你 –

+0

在这种情况下,你也可以使用更简单的* Array.reduce *函数作为* Array.fold *的特殊形式:'Array.reduce(*)[| 1; 2; 3; 4; 5 | ]' –

1

您可以使用Array.scan

​​
+0

注意,如果'arr'长度为'N','products'的长度是'N + 1' - 第一个元素是1 – torbonde

+0

谢谢李,与扫描,它很安静简单 –

0

其他已经给了很好的回答,只是一般性发言。你的陈述“或者一个递归函数”通常是不必要的。大约95%的时间,你可以使用折叠。如果您需要非标准的迭代顺序,那么递归函数是要走的路。

除此之外,不考虑如何一次完成整个操作,即如何处理您的案例中的数字列表,而只是考虑如何处理一个项目。

从那你你得到需要将项目与累加器相乘。因此,在这种情况下,您不再需要递归,因为您在迭代本身上抽象了折叠。

+0

非常感谢Daniel对您的评论 –

0

如果您想使用尾递归函数来完成这项工作。你可能会想尝试做某事类似:

let l = [1;2;3;4;5] 

let product lst = 
    let rec pTR acc = function 
     | [] -> acc 
     | h::t -> pTR (h * acc) t 
    pTR 1 lst 

product l