Tôi có chức năng đệ quy mà tôi đang cố gắng thực hiện @tailrec
bằng cách có phần bên trong, đệ quy (countR3
) thêm các phần tử vào hàng đợi (agenda
là scala.collections.mutable.Queue
). Ý tưởng của tôi là sau đó có phần bên ngoài của hàm lặp trong chương trình làm việc và tổng hợp kết quả.Có cách nào thanh lịch để foldLeft trên scala.collections.mutable.Queue đang phát triển không?
LƯU Ý: là vấn đề về bài tập về nhà, vì vậy tôi không muốn đăng toàn bộ mã; tuy nhiên, việc thực hiện đệ quy đuôi thực hiện là không phải là một phần của bài tập về nhà.
Dưới đây là phần mã liên quan đến câu hỏi của tôi:
import scala.collection.mutable.Queue
val agenda: Queue[Tuple2[Int, List[Int]]] = Queue()
@tailrec
def countR3(y: Int, x: List[Int]): Int = {
if (y == 0) 1
else if (x.isEmpty) 0
else if …
else {
agenda.enqueue((y - x.head, x))
countR3(y, x.tail)
}
}
⋮
agenda.enqueue((4, List(1, 2)))
val count = agenda.foldLeft(0) {
(count, pair) => {
val mohr = countR3(pair._1, pair._2)
println("count=" + count + " countR3=" + mohr)
count + mohr
}
}
println(agenda.mkString(" + "))
count
này gần dường như làm việc ... Vấn đề là nó không lặp qua tất cả các mục được bổ sung vào chương trình nghị sự, nhưng nó xử lý một số trong số đó. Bạn có thể thấy điều này trong đầu ra dưới đây: [. Trong số sáu mục trên chương trình nghị sự chính thức, chỉ có ba đầu tiên được xử lý]
count=0 countR3=0
count=0 countR3=0
count=0 countR3=0
(4,List(1, 2)) + (3,List(1, 2)) + (2,List(2)) + (2,List(1, 2)) + (1,List(2)) + (0,List(2))
Tôi thường cũng nhận thức được sự nguy hiểm của đột biến một bộ sưu tập trong khi bạn đang lặp qua nó trong, ví dụ, Java. Nhưng một Hàng đợi là loại ngựa có màu khác. Tất nhiên, tôi hiểu rằng tôi chỉ đơn giản là có thể viết một vòng lặp bắt buộc, như vậy:
var count = 0
while (!agenda.isEmpty) {
val pair = agenda.dequeue()
count += countR3(pair._1, pair._2)
}
này hoạt động hoàn hảo tốt, nhưng là Scala này, tôi khám phá để xem nếu có một hơn chức năng thanh lịch cách.
Mọi đề xuất?
Không chính xác thành ngữ, tôi đồng ý, nhưng có vẻ như nó sẽ phù hợp với hóa đơn hoạt động thuần túy hơn. Câu trả lời hay! Và thú vị là, 'chương trình nghị sự.foldLeft' đã được xử lý nhiều hơn chỉ là các mặt hàng enqueued ban đầu; nó không có vẻ đơn giản là làm việc trên một bản sao của hàng đợi ban đầu. Có lẽ nó đã dừng lại khi mục "cuối cùng" dẫn đến nhiều mục được thêm vào hàng đợi, hoặc một cái gì đó như thế. –