传递一个 Set[List[Int]] 类型的值而不是 List[Int] - 为什么这样做有效?

Passing a Set[List[Int]] typed value instead of List[Int] - why does that work?

当我查看签名和函数调用时,我很难理解以下内容。

在我的工作表中有以下内容(摘自 Coursera 讲座):

 object nqueens {

  def queens(n: Int) : Set[List[Int]] = {
    def placeQueens(k: Int) : Set[List[Int]] =
      if (k == 0) Set(List())
      else
      for  {
        queens <- placeQueens(k - 1)
        col <- 0 until n
        if isSafe(col, queens)
      } yield col :: queens
    placeQueens(n)
  }

  def isSafe(col: Int, queens: List[Int]) : Boolean = {
    val row = queens.length
    val queensWithRow = (row - 1 to 0 by -1) zip queens
    queensWithRow forall {
      case (r, c) => col != c && math.abs(col - c) != row -r
    }
  }

  def show(queens: List[Int]) = {
    val lines =
      for (col <- queens.reverse)
        yield Vector.fill(queens.length)("* ").updated(col, "X ").mkString
    "\n" + (lines mkString "\n")
  }

  (queens(4) map show) mkString "\n"

}

考虑 placeQueenisSafe 的签名:

def placeQueens(k: Int) : Set[List[Int]]

def isSafe(col: Int, queens: List[Int]) : Boolean

我不知道它为什么有效。我们调用 placeQueens 并将结果保存在 queens 中(在 for 循环中)。

结果应为 Set[List[Int]] 类型。然后我们用 IntSet[List[Int]] 两个参数调用 isSafe - 但我不明白为什么会这样,因为 queens 应该是 Set[List[Int]] 类型并且isSafe 的参数应该 List[Int].

We call placeQueens and save the result in queens (in the for loop).

不,您正在调用 placeQueens 并迭代结果。在每次迭代中,queens 引用当前元素。

We call placeQueens and save the result in queens

您的代码没有将 placeQueens 的结果保存到 queens 中。

for  {
    queens <- placeQueens(k - 1)
    col <- 0 until n
    if isSafe(col, queens)
  } yield col :: queens

这段代码其实是用来理解的。有问题的特定行:

queens <- placeQueens(k-1) 

正在将 List[Int] 存储到皇后区中,因为它正在迭代从 placeQueens 返回的 Set[List[Int]]。为了给出一个可能有助于说明正在发生的事情的更简单的示例,请考虑:

val a = Set(1,2,3)
val b = for (x <- a) yield x + 2

执行此代码后,b 将变为 Set(3,4,5)。这是因为在 for 循环的每次迭代中,x 首先是 1,然后是 2,然后是 3。