3

この問題を Scala で解決したいと考えています。私のコード:

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)

私のソリューションの次のステップは、シーケンスから豊富な数をすべて含むいくつかのシーケンスを作成することabNumbersです。強化された for ループでこれを実行しようとしましたが、実行時に Java Heap Exception がスローされます。これらすべての合計をストリーム構造に配置するにはどうすればよいですか?

4

2 に答える 2

2

範囲で toStream メソッドを使用します。

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

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

または、何か不足していますか?

于 2012-12-05T12:27:33.670 に答える
0

ストリームは無限シーケンスでうまく機能します。ただし、ここで自分の限界を知っています。関数型プログラミングの副産物として発生する可能性のあるすべての中間コレクションを回避したいだけです。(サイドノート: オイラー 23 は、控えめなハードウェアでも、粗暴な力ずくで実行できるはずです。ヒープが小さすぎるだけですか?)

主な関心事がメモリである場合は、ビューの使用を検討してください。ストリームと同様に、Scala のビューは遅延型です。しかし、セマンティクスは異なります。このことを考慮:

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

ここでの意図は関数合成ですが、途中でいくつかの中間コレクションが作成されmapますfilterビューは、パフォーマンス (メモリ効率による) と構成性の両方を得る 1 つのソリューションです。「開始」コレクションをビューとして作成するだけです。

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

ビューが実際に強制されると、変換 (および) は、異なる中間コレクションではSeqViewなく、1 つとして効果的に実行されます。これらは、SQL のテーブルのビューに似ていると考えてください。オイラー問題 23 の解決方法によっては、ビューが役立つ場合があります。これらは、Scala で遅延を活用する方法の 1 つにすぎません。ビュー、ストリーム、イテレーターの違いについては、この投稿を参照してください:ストリーム vs ビュー vs イテレーターSeqmapfilter

于 2012-12-05T17:33:51.297 に答える