Scala中的N-queens

时间:2017-03-14 15:17:26

标签: scala n-queens

  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)
  }

我不明白这段代码是如何工作的,即使我在Eclipse中调试也很难。你能解释一下这段代码吗?顺便说一句,代码正常工作。我也理解n-queens算法,但我不明白这个代码的机制。

1 个答案:

答案 0 :(得分:1)

让我们分解。

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)
}

我们定义一个函数queens(n: Int),它返回n * n棋盘上n个皇后的每个可能位置。函数queens本身非常简单;它只是委托给一个名为placeQueens的内部函数。

placeQueens首先列出了一个基本案例:如果我们在0 * 0棋盘上操作并放置0个皇后,那么只有一个(非常简单)的方法。现在,这个函数的内容是for循环。

for {
  queens <- placeQueens(k - 1)
  column <- 1 to n
  queen = (k, column)
  if isSafe(queen, queens)
} yield queen :: queens

部分内容可以像传统的&#34; for-loop,但其中一些并不那么简单。 Scala的for循环基于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

这些循环需要一些时间来适应。用手去看看循环(这是编译器做的事情)可能是有教育意义的。您可以找到翻译规则on the Scala website