当我使用List时,它可以正常工作,但是当我创建一个无限的流
时def foo = {
val s = Stream.from(1)
s.flatMap(x =>
s.flatMap(y =>
s.flatMap(z => f(x, y, z))))
}
当我调用
时,我收到了一个java.lang.OutOfMemoryErrorfoo.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)
我遇到了同样的问题
请帮忙。提前谢谢!
答案 0 :(得分:2)
看起来你正在尝试生成三元组,其中第一个成员大于第二个成员。首先,让我们生成一些像这样的对:
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
,在b
开始a+1
。
答案 1 :(得分:0)
这适用于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 [?]子类的类型。