我剛剛在Project Euler中解決了problem23,其中我需要集合來存儲所有豐富的數字。 F#有一個不可變的集合,我可以使用Set.empty.Add(i)
創建一個包含數字i
的新集合。但我不知道如何使用不可變集來做更復雜的事情。F#中不可變集合和映射的風格是什麼
例如,在下面的代碼中,我需要看看數字'x'是否可以寫成一個集合中兩個數字的總和。我使用排序的數組和二進制搜索算法來完成工作。
請也評論我的以下程序的風格。謝謝!
let problem23 =
let factorSum x =
let mutable sum = 0
for i=1 to x/2 do
if x%i=0 then
sum <- sum + i
sum
let isAbundant x = x < (factorSum x)
let abuns = {1..28123} |> Seq.filter isAbundant |> Seq.toArray
let inAbuns x = Array.BinarySearch(abuns, x) >= 0
let sumable x =
abuns |> Seq.exists (fun a -> inAbuns (x-a))
{1..28123} |> Seq.filter (fun x -> not (sumable x)) |> Seq.sum
更新版本:
let problem23b =
let factorSum x =
{1..x/2} |> Seq.filter (fun i->x%i=0) |> Seq.sum
let isAbundant x = x < (factorSum x)
let abuns = Set({1..28123} |> Seq.filter isAbundant)
let inAbuns x = Set.contains x abuns
let sumable x =
abuns |> Seq.exists (fun a -> inAbuns (x-a))
{1..28123} |> Seq.filter (fun x -> not (sumable x)) |> Seq.sum
這個版本在約27秒運行一次,而前23秒(我已經多次運行)。因此,與具有二分搜索的排序數組相比,不可變的紅黑樹實際上沒有太多速度下降。集合/數組中元素的總數是6965
。
注意:在最新版本的F#中,'Set.mem'被替換爲'Set.contains'。 – cfern 2010-01-10 11:23:53