我对 Scala 很陌生,所以请原谅我的无知!我正在尝试迭代以最大值为界的整数对。例如,如果最大值为 5,则迭代应返回:
(0, 0), (0, 1), ..., (0, 5), (1, 0), ..., (5, 5)
我选择尝试以递归方式将其作为流返回:
@tailrec
def _pairs(i: Int, j: Int, maximum: Int): Stream[(Int, Int)] = {
if (i == maximum && j == maximum) Stream.empty
else if (j == maximum) (i, j) #:: _pairs(i + 1, 0, maximum)
else (i, j) #:: _pairs(i, j + 1, maximum)
}
如果没有 tailrec 注释,代码可以工作:
scala> _pairs(0, 0, 5).take(11)
res16: scala.collection.immutable.Stream[(Int, Int)] = Stream((0,0), ?)
scala> _pairs(0, 0, 5).take(11).toList
res17: List[(Int, Int)] = List((0,0), (0,1), (0,2), (0,3), (0,4), (0,5), (1,0), (1,1), (1,2), (1,3), (1,4))
但这对我来说还不够好。编译器正确地指出 _pairs 的最后一行没有返回 _pairs:
could not optimize @tailrec annotated method _pairs: it contains a recursive call not in tail position
else (i, j) #:: _pairs(i, j + 1, maximum)
^
所以,我有几个问题:
- 直接解决上面的实现,尾递归如何返回 Stream[(Int, Int)]?
- 退后一步,迭代有界整数序列的最节省内存的方法是什么?我不想迭代 Range 因为Range 扩展 IndexedSeq,我不希望序列完全存在于内存中。还是我错了?如果我遍历 Range.view 我会避免它进入内存吗?
在 Python(!)中,我想要的只是:
In [6]: def _pairs(maximum):
...: for i in xrange(maximum+1):
...: for j in xrange(maximum+1):
...: yield (i, j)
...:
In [7]: p = _pairs(5)
In [8]: [p.next() for i in xrange(11)]
Out[8]:
[(0, 0),
(0, 1),
(0, 2),
(0, 3),
(0, 4),
(0, 5),
(1, 0),
(1, 1),
(1, 2),
(1, 3),
(1, 4)]
谢谢你的帮助!如果您认为我需要阅读参考资料/API 文档/其他任何内容,请告诉我,因为我很想学习。