2012-12-05 30 views
3

我想解決在斯卡拉this問題。 我的代碼:歐拉23斯卡拉堆大小異常

def dividers(n: Int) = 
    (1 until n) filter (x => n%x == 0) 

def sumOfDividers(n: Int) = dividers(n).sum 

val abNumbers = (1 to 28123) filter (x => sumOfDividers(x) > x) 

下一步我solutios是要包含所有可能的豐富許多來自abNumbers序列的一些序列。我試圖用增強for循環來做到這一點,但它在運行時拋出Java堆異常。我怎樣才能將所有這些總和放到流結構中?

+0

我假定'Java堆異常'是OutOfMemoryException。但是,即使給進程使用2Mb的內存,它也可以成功完成,無論有沒有流。 –

+0

@DenisTulskiy true。 –

+0

@DenisTulskiy確實 - 也許我們想看看OP的'enahanced for loop'? – Faiz

回答

2

使用範圍上的toStream方法:

val abNumbers = ((1 to 28123) toStream).filter (x => sumOfDividers(x) > x) 

abNumbers: scala.collection.immutable.Stream[Int] = Stream(12, ?) 

還是我失去了一些東西?

+0

將'Stream'保存爲'val'不是一個好主意。 – senia

+1

@senia爲什麼?你能擴展嗎? –

+0

對Stream的引用是對它的第一個元素的引用。 GC是無奈的,而這個參考是活着的。 – senia

0

流與很好地工作無限序列。但是,在這裏你知道你的界限;你只想避免所有可能作爲函數式編程的副產品出現的中間集合。 (旁註:歐拉23應在揮霍蠻力甚至一般硬體上是可行的,它只是你的堆也許是太小)

如果您主要關注的是記憶,也可以考慮使用意見 。像Streams一樣,Scala中的視圖是懶惰的。但是語義不同。試想一下:

(1 to 100000) map (_+1) filter (x => x % 2 == 0) map (x => x*x) 

這樣做的目的是函數組合,但是這會在途中創建多箇中間集合:每個mapfilter將返回一個新的,潛在的同等大小的集合。 查看是一個解決方案,同時獲得性能(通過存儲效率)和組合性:你剛纔創建「開始」集合爲一個觀點:

(1 to 100000 view) map (_+1) filter (x => x % 2 == 0) map (x => x*x) 

這將很快返回SeqView,而不是通常的Seq - 當該視圖實際上是強制的,您的轉換(在mapfilter中)作爲一個有效完成,而不是在不同的中間集合上。把它們看作類似於SQL中表的視圖。根據你計劃如何解決歐拉問題23,視圖可能會有所幫助。它們只是在Scala中利用懶惰的方式之一 - 請參閱本文以瞭解視圖,流和迭代器之間的差異:Stream vs Views vs Iterators