Lassen Sie uns es brechen.
def queens(n: Int): List[List[(Int, Int)]] = {
def placeQueens(k: Int): List[List[(Int, Int)]] =
if (k == 0)
List(List())
else
for {
queens <- placeQueens(k - 1)
column <- 1 to n
queen = (k, column)
if isSafe(queen, queens)
} yield queen :: queens
placeQueens(n)
}
Wir definieren eine Funktion queens(n: Int)
, die jede mögliche Platzierung von n Damen auf einem n * n Schachbrett zurückgibt. Die Funktionen queens
selbst sind sehr einfach; Es delegiert nur an eine innere Funktion namens placeQueens
.
placeQueens
hat einen Basisfall zuerst aufgelistet: Wenn wir auf einem 0 * 0 Schachbrett operieren und 0 Königinnen platzieren, gibt es genau einen (sehr trivialen) Weg es zu tun. Jetzt ist das Fleisch dieser Funktion in der For-Schleife.
Teile davon können wie eine "traditionelle" for-Schleife gelesen werden, aber einige davon sind nicht so einfach. Die For-Schleife von Scala basiert auf der Haskell-Do-Loop-Syntax, die wahrscheinlich einige Ihrer Verwirrung erklärt. Der Weg dies zu lesen ist:
// We're starting a for-loop
for {
// Call placeQueens recursively. placeQueens returns a list of
// all possible results, so iterate over them.
queens <- placeQueens(k - 1)
// Iterate over each column that the kth queen could go in.
column <- 1 to n
// Assign the queen to that position.
queen = (k, column)
// If the position is safe, keep going. More precisely, if the position
// is NOT safe, stop.
if isSafe(queen, queens)
// Put our new queen assignment at the beginning of the recursively computed list.
} yield queen :: queens
Diese Schleifen sind gewöhnungsbedürftig. Es kann lehrreich sein, die Schleife (die der Compiler sowieso macht) manuell zu entziffern, um zu sehen, was es bedeutet. Sie können die Übersetzungsregeln on the Scala website finden.
'if (k == 0) List (Liste()) sonst für { queens <- placeQueens (k - 1)' Hier ist der Punkt: In dem Teil des Codes als links, wenn Ich debugge, k iteriert zu 4,3,2,1,0, wenn die Aussage wahr ist. Danach ist k gleich 1. Wie ist es möglich? – coder
@coder, Wenn 'k == 0' dann wird eine leere 'List()' von dieser Iteration_ zurückgegeben. Zurück zu wo? Zurück zur vorherigen Iteration mit 'k == 1'. Wenn Sie weiter durch den Code gehen, sollten Sie sehen, dass die aktuelle Iteration vom 'yield', im' else'-Block, zum _previous iteration_ zurückkehrt, wo 'k == 2' ist, und so weiter. – jwvh
"Zurück zur vorherigen Iteration, wo" k == 1 "" das ist wirklich seltsam und verwirrend. Gibt es ein klareres Beispiel für die for-Schleife und Rekursion in Scala. – coder