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。如何将所有这些总和放入 Stream 结构中?

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 也应该可以在挥霍的蛮力中使用;只是你的堆可能太小了吗?)

如果您主要关心的是内存,请考虑使用views。与 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) 

这将很快返回 aSeqView而不是通常的Seq- 当视图实际上是强制的时,你的转换(inmapfilter)实际上是作为一个而不是在不同的中间集合上完成的。将它们视为类似于 SQL 中表的视图。根据您计划如何解决欧拉问题 23,视图可能会有所帮助。它们只是在 Scala 中利用惰性的一种方式 - 请参阅这篇文章了解视图、流和迭代器之间的区别:Stream vs Views vs Iterators

于 2012-12-05T17:33:51.297 回答