我认为跟踪通话记录可以帮助您更好地理解它。我将编号步骤,以便轻松地来回切换。
combinations(List(('a', 2), ('b', 2)))
, we have first:
(char, max) <- ('a', 2)
count <- 1
The result of occurrences filter {case (c, _) => c > char}
will be List(('b', 2))
.
Therefore we now calculate combinations(List(('b', 2)))
:
(char, max) <- ('b', 2)
count <- 1
Now, the result of occurrences filter {case (c, _) => c > char}
will be List()
.
We are going to calculate combiantions(List())
:
The for comprehension will be List()
, and List() :: List()
results in List()
. Therefore we are back in step 2:
(step 2) We had:
(char, max) <- ('b', 2)
count <- 1
and now we have no elements for rest. So the result of step 2 will be List() :: List()
which is List()
as well. Back to step 1. So we are going to yield for that option List((char, count)) ++ rest)
which is: List(('b', 1)) ++ List())
which is List(('b', 1))
We are now in the next iteration of the same call with:
(char, max) <- ('b', 2)
count <- 2
rest
will be List()
again and we are now going to yield for that option List((char, count)) ++ rest)
which is: List(('b', 2)) ++ List())
which is List(('b', 2))
. Now we have to add the empty list, and the result is: List(List(), List((b,1)), List((b,2)))
.
(step 1) We had:
(char, max) <- ('a', 2)
count <- 1
and now we have:
rest <- List()
So we are yielding List((char, count)) ++ rest
which is: List(('a', 1)) ++ List()
which is: List(('a', 1))
Now we continue to:
rest <- List((b,1))
So we are yielding List((char, count)) ++ rest
which is: List(('a', 1)) ++ List((b,1))
which is: List(('a', 1), ('b', 1))
.
Now we continue to:
rest <- List((b,2))
So we are yielding List((char, count)) ++ rest
which is: List(('a', 1)) ++ List((b,2))
which is: List(('a', 1), ('b', 2))
. The aggregated result so far is:
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)))
List((char, count)) ++ res
会使整个过程极其低效。请改为使用(char, count) :: res
。 - Luis Miguel Mejía Suárez::
results in a type errorfound : List[List[Equals with java.io.Serializable]] required: List[forcomp.Anagrams.Occurrences] (which expands to) List[List[(Char, Int)]] List() :: (for {```
- Jonny Waffles