我有一個遞歸函數,我試圖讓內部遞歸部分(countR3
)添加元素到隊列(agenda
是scala.collections.mutable.Queue
)@tailrec
。我的想法是,然後讓該功能的外部部分摺疊在議程上並總結結果。有沒有一種優雅的方式來摺疊不斷增長的scala.collections.mutable.Queue?
注意:這是一個作業問題,因此我不想發佈整個代碼;然而,使得實現尾遞歸的是而不是作業的一部分。
下面是代碼的有關我的問題的一部分:
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
這幾乎似乎工作...問題是,它並沒有遍歷所有的項目列入議程,但它確實處理了其中的一些。您可以在下面的輸出看到這一點:[最終議程的六個項目中,只有前三個分別處理]
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))
我一般也感知突變的危害一個集合,當你在Java中迭代它時。但是隊列是一種不同顏色的馬。當然,我知道我可以簡單地寫勢在必行循環,就像這樣:
var count = 0
while (!agenda.isEmpty) {
val pair = agenda.dequeue()
count += countR3(pair._1, pair._2)
}
這工作得很好,但是這是斯卡拉,我探索,看看是否有更功能優雅方式。
有什麼建議嗎?
不完全是慣用的,我同意,但它確實似乎適合更純粹的功能。很好的答案!有趣的是,議程。foldLeft'不僅僅處理最初入隊的項目,它似乎不是簡單地在初始隊列的副本上工作。也許當「最後」項目導致更多項目被添加到隊列中時,它會停止,或者類似的東西。 –