我认为跟踪电话将帮助您更好地理解它。我将对步骤进行编号,以便在它们之间轻松地来回切换。
-
combinations(List(('a', 2), ('b', 2))),我们先:
(char, max) <- ('a', 2)
count <- 1
occurrences filter {case (c, _) => c > char} 的结果将是List(('b', 2))。
-
因此我们现在计算combinations(List(('b', 2))):
(char, max) <- ('b', 2)
count <- 1
现在,occurrences filter {case (c, _) => c > char} 的结果将是 List()。
-
我们要计算combiantions(List()):
for 理解将是List(),List() :: List() 的结果是List()。因此我们回到第 2 步:
-
(第 2 步)我们有:
(char, max) <- ('b', 2)
count <- 1
现在我们没有休息的元素了。所以第 2 步的结果将是List() :: List(),也就是List()。回到第 1 步。因此,我们将为该选项屈服 List((char, count)) ++ rest),即:List(('b', 1)) ++ List()),即List(('b', 1)),我们现在处于同一调用的下一次迭代中:
(char, max) <- ('b', 2)
count <- 2
rest 将再次变为List(),我们现在将为该选项屈服List((char, count)) ++ rest),即:List(('b', 2)) ++ List()),即List(('b', 2))。现在我们要添加空列表,结果是:List(List(), List((b,1)), List((b,2)))。
-
(第 1 步)我们有:
(char, max) <- ('a', 2)
count <- 1
现在我们有了:
rest <- List()
所以我们产生List((char, count)) ++ rest 即:List(('a', 1)) ++ List() 即:List(('a', 1))
现在我们继续:
rest <- List((b,1))
所以我们产生了List((char, count)) ++ rest,即:List(('a', 1)) ++ List((b,1)),即:List(('a', 1), ('b', 1))。
现在我们继续:
rest <- List((b,2))
所以我们得到List((char, count)) ++ rest,即:List(('a', 1)) ++ List((b,2)),即:List(('a', 1), ('b', 2))。到目前为止的汇总结果是:
List(List(('a', 1)), List(('a', 1), ('b', 1)), List(('a', 1), ('b', 2)))
现在max 将增加到 2,我们将在步骤 2-4 中进行相同的计算,这将产生,具有完全相同的逻辑:
List(List(('a', 2)), List(('a', 2), ('b', 1)), List(('a', 2), ('b', 2)))
现在(char, max) 将更改为('b', 2),这将导致它(在应用步骤 2-4 中的相同逻辑之后):
List(List(('b', 1)), List(('b', 2)))
当聚合在一起时,我们得到想要的输出。
真正有助于了解我刚才解释的内容是添加打印消息:
def combinations(occurrences: Occurrences): List[Occurrences] = {
println("Starting with: " + occurrences)
val result = List() :: (for {
(char, max) <- occurrences
count <- 1 to max
rest <- combinations(occurrences filter {case (c, _) => c > char })
} yield {
val result = List((char, count)) ++ rest
println("Occurrences are: " + occurrences + " Result is: " + result)
result
})
println("Done with: " + occurrences + " results are: " + result)
result
}
然后调用println("Done: " + combinations(List(('a', 2), ('b', 2)))) 的结果是:
Starting with: List((a,2), (b,2))
Starting with: List((b,2))
Starting with: List()
Done with: List() results are: List(List())
Occurrences are: List((b,2)) Result is: List((b,1))
Starting with: List()
Done with: List() results are: List(List())
Occurrences are: List((b,2)) Result is: List((b,2))
Done with: List((b,2)) results are: List(List(), List((b,1)), List((b,2)))
Occurrences are: List((a,2), (b,2)) Result is: List((a,1))
Occurrences are: List((a,2), (b,2)) Result is: List((a,1), (b,1))
Occurrences are: List((a,2), (b,2)) Result is: List((a,1), (b,2))
Starting with: List((b,2))
Starting with: List()
Done with: List() results are: List(List())
Occurrences are: List((b,2)) Result is: List((b,1))
Starting with: List()
Done with: List() results are: List(List())
Occurrences are: List((b,2)) Result is: List((b,2))
Done with: List((b,2)) results are: List(List(), List((b,1)), List((b,2)))
Occurrences are: List((a,2), (b,2)) Result is: List((a,2))
Occurrences are: List((a,2), (b,2)) Result is: List((a,2), (b,1))
Occurrences are: List((a,2), (b,2)) Result is: List((a,2), (b,2))
Starting with: List()
Done with: List() results are: List(List())
Occurrences are: List((a,2), (b,2)) Result is: List((b,1))
Starting with: List()
Done with: List() results are: List(List())
Occurrences are: List((a,2), (b,2)) Result is: List((b,2))
Done with: List((a,2), (b,2)) results are: List(List(), List((a,1)), List((a,1), (b,1)), List((a,1), (b,2)), List((a,2)), List((a,2), (b,1)), List((a,2), (b,2)), List((b,1)), List((b,2)))
Done: List(List(), List((a,1)), List((a,1), (b,1)), List((a,1), (b,2)), List((a,2)), List((a,2), (b,1)), List((a,2), (b,2)), List((b,1)), List((b,2)))