하자.
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)
}
우리는 n의 * n 개의 체스 판에 N 여왕의 가능한 모든 위치를 반환하는 함수 queens(n: Int)
을 정의합니다. 함수 queens
은 매우 간단합니다. placeQueens
이라는 내부 함수에 위임합니다.
placeQueens
은 기본 케이스가 먼저 나열되어 있습니다. 우리가 0 * 0 체스 판에서 작동하고 0 명의 왕비를 배치한다면, 정확히 한 가지 (매우 사소한) 방법이 있습니다. 자,이 함수의 고기는 for-loop에 있습니다.
for {
queens <- placeQueens(k - 1)
column <- 1 to n
queen = (k, column)
if isSafe(queen, queens)
} yield queen :: queens
이 부분은 "for"루프처럼 읽을 수 있지만 그 중 일부는 그리 간단하지 않습니다. 스칼라의 for-loop는 Haskell의 Do-Loop 구문을 기반으로합니다.이 구문은 아마도 혼란을 설명 할 것입니다. 이를 읽는 방법은 다음과 같습니다.
// 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
이러한 루프는 익숙해 져 있습니다. 그것이 의미하는 바를보기 위해 루프를 desugar (컴파일러가 어쨌든 수행하는 것입니다)하는 것이 교육적 일 수 있습니다. 번역 규칙 on the Scala website을 찾을 수 있습니다.
'<{ 퀸위한 다른 (K == 0) 리스트 (리스트()) 경우 - placeQueens (K - 1)' 여기서 요점은 : 코드 부분에서는 때 채 나는 디버깅 중이며, k는 4,3,2,1,0으로 반복된다. if 문이 참이다. 그 후에 k는 1과 같습니다. 어떻게 가능합니까? – coder
@coder,'k == 0 '일 때,이 반복에서 빈'List()'가 반환됩니다. 어디로 돌아 왔습니까? 'k == 1'인 이전 반복으로 돌아 감. 코드를 계속 진행한다면'else' 블록의'yield','k == 2' 등의 이전 iteration_에 대한 현재 반복 결과를 볼 수 있습니다. – jwvh
"이전 반복에서'k == 1'이 반환됩니다. 이것은 정말 이상하고 혼란 스럽습니다. 스칼라에서 for 루프와 재귀를 포함하여보다 명확한 예제가 있는가? – coder