当我使用列表时,它可以正常工作,但是当我创建一个无限的流时
def foo = {
val s = Stream.from(1)
s.flatMap(x =>
s.flatMap(y =>
s.flatMap(z => f(x, y, z))))
}
当我调用时,我收到一个java.lang.OutOfMemoryError。
foo.take(10)
关于 f
def f(x: Int, y: Int, z: Int) = {
if(Math.pow(x, 2) + Math.pow(y, 2) == Math.pow(z, 2) )
else None
}
最初,我以为只有当我为这 10 个元素调用它时才会被评估,但我知道我不确定。我在Iterator.from(1)
遇到了同样的问题请帮忙。提前谢谢你!
看起来您正在尝试生成第一个成员大于第二个成员的三元组。 首先,让我们生成一些这样的对:
scala> def natNums = Iterator from 1
natNums: Iterator[Int]
scala> def foo = for { x <- natNums; y <- 1 until x } yield (x,y)
foo: Iterator[(Int, Int)]
scala> (foo take 15).toList
res4: List[(Int, Int)] = List((2,1), (3,1), (3,2), (4,1), (4,2), (4,3), (5,1), (5,2), (5,3), (5,4), (6,1), (6,2), (6,3), (6,4), (6,5))
我走在正确的轨道上吗?
好的,现在您要向元组添加第三个成员。 好吧,如果我们类似地将 z 约束为小于 y,它就可以正常工作:
scala> def foo = for { x <- natNums; y <- 1 until x; z <- 1 until y } yield (x,y,z)
foo: Iterator[(Int, Int, Int)]
scala> (foo take 15).toList
res1: List[(Int, Int, Int)] = List((3,2,1), (4,2,1), (4,3,1), (4,3,2), (5,2,1), (5,3,1), (5,3,2), (5,4,1), (5,4,2), (5,4,3), (6,2,1), (6,3,1), (6,3,2), (6,4,1), (6,4,2))
但是如果 z 不受约束,我不明白您希望程序做什么。 只需从natNums中绘制z,就可以将CPU变成烤面包机:
scala> def foo = for { x <- natNums; y <- 1 until x; z <- natNums } yield (x,y,z)
foo: Iterator[(Int, Int, Int)]
scala> (foo take 15).toList
^C
你能给我们你期望的输出吗?
更新:啊! 毕达哥拉斯三元组——多么有趣!
这是一个简单的生成器,我称之为"原始"毕达哥拉斯三元组,因为它包含需要过滤掉的倍数。 例如,(6,8,10) 不应算作毕达哥拉斯三元组,因为它是 (3,4,5) 的倍数。 我会把它留给你,因为我认为阻碍你的只是首先生成数字的部分。 如果需要,请随时在另一个StackOverflow问题中寻求帮助。
scala> def rawPythagTriples =
for { c <- Iterator from 1; a <- 1 until c; b <- a until c if a*a + b*b == c*c }
yield (a,b,c)
rawPythagTriples: Iterator[(Int, Int, Int)]
scala> (rawPythagTriples take 10).toList
res2: List[(Int, Int, Int)] = List((3,4,5), (6,8,10), (5,12,13), (9,12,15), (8,15,17), (12,16,20), (7,24,25), (15,20,25), (10,24,26), (20,21,29))
请注意,我们从斜边开始,从而约束a
和b
。 顺便说一下,您可以进行一些小的优化,例如从 5 开始c
,从 2 开始a
,在 a+1
开始b
。
在 REPL 中有效:
def foo = {
val s = Stream.from(1)
s.flatMap(x =>
s.flatMap(y =>
s.flatMap(z => List(x,y,z))))
}
scala> foo.take(15) mkString ", "
res24: String = 1, 1, 1, 1, 1, 2, 1, 1, 3, 1, 1, 4, 1, 1, 5
您的 f(x,y,z) 必须返回一个扩展 GenTraversableOnce[?] 子类的类型。