這實際上是F#中的項目Euler Problem 14的解決方案。但是,當試圖計算大數的迭代序列時,我遇到了System.OutOfMemory異常。正如你所看到的,我正在用tail調用寫我的遞歸函數。帶遞歸調用的F#System.OutOfMemoryException
由於我在Visual Studio中調試(禁用尾部調用),我遇到了StackOverFlowException的問題。我已經記錄了in another question。在這裏,我以發佈模式運行 - 但是當我將其作爲控制檯應用程序運行時(在使用4gb ram的windows xp上)時,出現內存異常。
我真的很難理解我是如何編碼自己到這個內存溢出&希望有人能以我的方式顯示我的錯誤。
let E14_interativeSequence x =
let rec calc acc startNum =
match startNum with
| d when d = 1 -> List.rev (d::acc)
| e when e%2 = 0 -> calc (e::acc) (e/2)
| _ -> calc (startNum::acc) (startNum * 3 + 1)
let maxNum pl=
let rec maxPairInternal acc pairList =
match pairList with
| [] -> acc
| x::xs -> if (snd x) > (snd acc) then maxPairInternal x xs
else maxPairInternal acc xs
maxPairInternal (0,0) pl
|> fst
// if I lower this to like [2..99999] it will work.
[2..99999]
|> List.map (fun n -> (n,(calc [] n)))
|> List.map (fun pair -> ((fst pair), (List.length (snd pair))))
|> maxNum
|> (fun x-> Console.WriteLine(x))
編輯
鑑於通過答案的建議,我重寫使用一個懶惰的清單,並使用的Int64的。
#r "FSharp.PowerPack.dll"
let E14_interativeSequence =
let rec calc acc startNum =
match startNum with
| d when d = 1L -> List.rev (d::acc) |> List.toSeq
| e when e%2L = 0L -> calc (e::acc) (e/2L)
| _ -> calc (startNum::acc) (startNum * 3L + 1L)
let maxNum (lazyPairs:LazyList<System.Int64*System.Int64>) =
let rec maxPairInternal acc (pairs:seq<System.Int64*System.Int64>) =
match pairs with
| :? LazyList<System.Int64*System.Int64> as p ->
match p with
| LazyList.Cons(x,xs)-> if (snd x) > (snd acc) then maxPairInternal x xs
else maxPairInternal acc xs
| _ -> acc
| _ -> failwith("not a lazylist of pairs")
maxPairInternal (0L,0L) lazyPairs
|> fst
{2L..999999L}
|> Seq.map (fun n -> (n,(calc [] n)))
|> Seq.map (fun pair -> ((fst pair), (Convert.ToInt64(Seq.length (snd pair)))))
|> LazyList.ofSeq
|> maxNum
它解決了這個問題。儘管如此,我也會看到尹's的解決方案更好。
正如@Brian指出的,Seq更適合這個問題。事實上,在研究Euler項目中的前45個問題後,我發現幾乎所有的問題都適用於基於Seq的解決方案。如果你有興趣,這是我對問題14的解決方案:http://projecteulerfun.blogspot.com/2010/05/problem-14-which-starting-number-under.html(當然,你可能想等待直到你將你的工作滿意爲止,或者你可能已經滿足於你的算法,但希望看到基於Seq的實現的外觀)。 – 2010-11-09 00:50:52
警告,除了OutOfMemoryException外,還有至少一個其他問題,您的解決方案可能會因查看我的解決方案而被破壞。 – 2010-11-09 00:53:24