2009-08-26 53 views
1

下面的C#代碼:F# - 如何以遞歸方式編寫嵌套循環?

var product = new List<int>(); 
for (int n1 = 100; n1 < 1000; n1++) 
{ 
    for (int n2 = 100; n2 < 1000; n2++) 
    { 
     product.Add(n1 * n2); 
    } 
} 

什麼是寫在一個實用的風格等效F#代碼?

+0

我不知道F#,但我知道其他函數式語言,我可以提供一些建議:首先將內部(更多嵌套)循環轉換爲遞歸函數。然後,將外部循環轉換爲調用內部循環函數的遞歸函數應該更容易。 – Imagist 2009-08-26 16:01:29

回答

5

布賴恩建議的解決方案絕對是最好的選擇(在F#中)。序列表達式讓你更容易表達你的意思,所以爲什麼不使用它們?

無論如何,如果你這樣做只是作爲一個鍛鍊; Tibial,那麼你可以重寫嵌套循環單遞歸函數和外環的第二(如意象建議):

let product = 
    let rec outer(n1) = 
    let rec nested(n2) = 
     if n2 > 4 then [] else (n1 * n2)::(nested(n2 + 1)) 
    if n1 > 4 then [] else nested(2) @ outer(n1 + 1) 
    outer(2) 

我在嵌套函數中使用::將元素追加到開頭,並使用@來連接由各個嵌套函數調用生成的列表。使用@是不是很有效,代碼也不是尾遞歸,所以最好使用版本蓄參數是這樣的:

let product = 
    let rec outer n1 acc = 
    let rec nested n2 acc = 
     if n2 > 4 then acc else nested (n2 + 1) ((n1 * n2)::acc) 
    if n1 > 4 then acc else outer (n1 + 1) (nested 2 acc) 
    outer 2 [] |> List.rev 

希望這有助於!

13

我只是用for-loops這樣寫的。即使是Haskell程序員也可能會用列表理解來表達,在這種情況下,您可以編寫例如

let productsList = 
    [for x in 2..4 do 
    for y in 2..4 do 
    yield x*y] 

in F#。

+0

你錯過了語法糖,但我認爲這不適合這種情況。 ( - > == do yield) let productsList = [for x in 2 .. 4 do for y in 2..4 - > x * y] – 2009-08-27 18:57:32