Tôi rất mới với Scala, vì vậy hãy tha thứ cho sự thiếu hiểu biết của tôi! Tôi đang cố gắng để lặp đi lặp lại của cặp số nguyên được giới hạn bởi một tối đa. Ví dụ, nếu mức tối đa là 5, sau đó lặp nên quay lại:Luồng nối tiếp đệ quy của các cặp số nguyên (Scala)?
(0, 0), (0, 1), ..., (0, 5), (1, 0), ..., (5, 5)
tôi đã chọn để thử và đuôi-đệ quy quay trở lại này như một Stream:
@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)
}
Nếu không có chú thích tailrec sự mã hoạt động:
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))
Nhưng điều này không đủ tốt cho tôi. Trình biên dịch được một cách chính xác chỉ ra rằng dòng cuối cùng của _pairs không trả _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)
^
Vì vậy, tôi có một vài câu hỏi:
- trực tiếp giải quyết việc thực hiện ở trên, như thế nào trở lại một đuôi-đệ quy Luồng [(Int, Int)]?
- thực hiện một bước trở lại, cách hiệu quả nhất về bộ nhớ để lặp qua chuỗi các số nguyên bị chặn là gì? Tôi không muốn lặp qua Phạm vi vì Range extends IndexedSeq và tôi không muốn chuỗi đó tồn tại hoàn toàn trong bộ nhớ. Hoặc là tôi sai? Nếu tôi lặp qua Range.view thì tôi có tránh nó vào bộ nhớ không? (!)
Trong Python, tất cả tôi muốn là:
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)]
Nhờ sự giúp đỡ của bạn! Nếu bạn nghĩ rằng tôi cần phải đọc tài liệu tham khảo/tài liệu API/bất cứ điều gì khác xin vui lòng cho tôi biết, bởi vì tôi rất muốn học.
Cảm ơn câu trả lời của bạn! Tôi hiểu tại sao những gì tôi đã làm không phải là đệ quy đuôi, và tôi chắc chắn muốn sử dụng 'for'. Vấn đề tôi có là 'cặp', như bạn đã đề xuất, trả về' IndexedSeq'. Do đó toàn bộ kết quả sẽ tồn tại trong bộ nhớ khi 'cặp' được gọi. Bạn có thể vui lòng giải thích cách sử dụng chế độ xem để tránh điều này không? –
Và bạn có biết thêm chi tiết và tham chiếu về luồng và đoạn không? Tôi rất tò mò về cách tôi sẽ không thổi tung ngăn xếp bằng cách đệ quy gọi một hàm tối ưu hóa cuộc gọi không đuôi mà tôi không sử dụng coroutines. Vì vậy, nhiều để tìm hiểu! –
@AsimIhsan: Tôi sẽ trả lời các câu hỏi này trong bản chỉnh sửa. –