【问题标题】:Recursive call in a for yield structure in Scala [duplicate]Scala中的收益结构中的递归调用[重复]
【发布时间】:2021-03-11 10:37:51
【问题描述】:

我对 Coursera 的以下 Scala 代码感到困惑。这段代码的目的是在一个箱子板上放置 n 个皇后,这样没有皇后相互威胁,即同一行、同一列或对角线。

  1. 递归调用PlaceQueen(k-1) 的评估如何在从 k =0 到 k = n 的每个步骤中进行? yield col::queens 行中是否发生了递归调用 PlaceQueen(k-1)

  2. 如果col::queens 将前面行的列追加为列表,则yield col::queens 的输出应该是列列表。但是它是如何转化为 Set of list 的呢?

         object nQueens extends App{
    
         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 queensWithRows = (row - 1 to 0 by -1) zip queens
              queensWithRows forall {
              case (c, r) => col != c && math.abs(col - c) != row - r
               }
            }
    
    
           queens(4)
    
           }
    

输出是: Set(List(1,3,0,2), List(2,0,3,1))

【问题讨论】:

  • 如果您可以发布可编译的代码,这会有所帮助。我已经修复了一些明显的错误,但仍然不正确或不完整。

标签: list scala recursion set


【解决方案1】:

忽略所有导致代码无法按预期执行的问题,您的问题的答案是:

它是如何转化为一组列表的?

因为for 中的第一个集合是Set,所以它被转换了。之所以设置它是因为Set 被定义为placeQueens 的返回类型。

queens &lt;- placeQueens(k-1)

这也回答了你的第一个问题:

有没有递归调用placeQueen(k-1)?

因为这是递归调用的地方。

【讨论】:

    【解决方案2】:

    这段代码有多个无限循环。

    queens 方法简单调用自己,这显然是不正确的:

    def queens(n:Int):Set[List[Int]] = {
      def placeQueens(k:Int):Set[List[Int]] = ???
      def isSafe(col: Int, queens:List[Int]):Boolean = ???
    
      queens(4)
    }
    

    placeQueens 方法在经过一些计算后也会调用自身:

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

    【讨论】:

      猜你喜欢
      • 2011-05-14
      • 2013-09-28
      • 1970-01-01
      • 2012-11-10
      • 1970-01-01
      • 2020-11-20
      • 2015-04-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多