2014-05-06 225 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