Scala 中的 N 皇后

2023-12-12

  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算法,但我不明白这段代码的机制。


让我们来分解一下。

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

其中部分内容可以像“传统”for 循环一样阅读,但其中一些内容并不那么简单。 Scala 的 for 循环基于 Haskell 的 do 循环语法,这可能解释了您的一些困惑。阅读本文的方法是:

// 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

这些循环需要一些时间来适应。手动对循环进行脱糖(编译器无论如何都会这样做)以了解其含义是很有教育意义的。你可以找到翻译规则在斯卡拉网站上.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Scala 中的 N 皇后 的相关文章

随机推荐

  • 如何使用 mysql 创建每周队列分析表?

    假设您有一个用户表 其中至少包含用户注册的日期和 ID 现在 假设您有一个单独的表 用于跟踪可能在用户生命周期中的任何时刻发生的操作 例如付款 比如应用内购买 在该表中 我们跟踪用户 ID 付款日期和付款 ID 所以我们有类似这样的东西来设
  • 使用地理编码初始化 React Google Maps StandaloneSearchBox

    有人可以告诉我如何使用类型初始化React Google Maps的StandaloneSearchBox组件 geocode 就像原始的google maps places Autocomplete一样 这样我就可以限制自动完成的输入建议
  • 使用 Json.Net 在 C# 中解析 Json

    Posts id 1 title Bibidh prothom khondo content sjih sdkljjdsf kdjsfjks author last update 23 june 2013 Comments id 1 con
  • 复选框 + Jquery 隐藏/显示

    我有一系列的行和复选框来过滤它们 ul li li ul
  • 表中可编辑字段之间的 Tab 键切换

    我正在使用这里的代码http www korvus com blog geek making the tab key work with jeditable fields 在 jeditable 字段之间进行制表符工作 如果这些字段是独立的
  • INSERT 语句与 FOREIGN KEY 约束“FK_PostTag_Tag_TagId”冲突

    我在用实体框架 7 RC1我有实体 public class Post public Int32 Id get set public String Title get set public virtual IList
  • 最后进入异常处理

    到底是什么作用finally阻止异常处理执行 它保存应该始终执行的代码 无论是否发生异常 例如 如果您打开了一个文件 则应该在finally阻止以确保它始终处于关闭状态 如果您将其关闭try块 较早的异常将导致执行直接跳转到catch阻止并
  • Shunting-Yard VS 递归下降解析器

    我正在构建一个高级数学解析器 并且想知道 Shunting Yard 和其他可用解析器算法 例如 Descent Parser 之间的区别 因为我更喜欢以 RPN 表示法存储公式 提前致谢 我从来没有太多使用 调车场 算法 因为它似乎只关注
  • 如何为从 NIB 加载的 NSWindow 提供焦点?

    我在用着NSWindowController从 NIB 加载窗口 然而 当我打电话时showWindow 该窗口在视觉上位于最上面 但焦点仍保持在原来的位置 而不是将其移动到新窗口 It s easy to see this happeni
  • java中的日历日期为yyyy-MM-dd格式

    如何将日历日期转换为yyyy MM dd format Calendar cal Calendar getInstance cal add Calendar DATE 1 Date date cal getTime SimpleDateFo
  • 为什么 pytesseract 不能识别单个数字?

    I am performing ocr on a site and specifically on these two images 我对 OCR 相当陌生 我使用以下内容 from PIL import Image import pyte
  • 如何使用 jQuery 增加数量字段的值?

    我有一个带有一些数量字段的表格 每一侧都有一个加号和减号
  • .NET 中的网络文件复制

    我有一个运行 Samba 共享的 Ubuntu 盒子 向所有人开放 我可以通过 ip 地址访问它 所以我知道我可以完全访问它 在我的应用程序中 我正在尝试以下操作 但它无法通过 IP 地址 仅 DNS 名称 工作 val ip addres
  • 有没有更好的方法来设置 JPanel 图形的初始位置?)

    在梁的第15章中Java 编程简介 第七版 他介绍了一个程序 可以在 JPanel 上制作一个 2 D 球 并通过单击放大 缩小按钮来放大它 我修改了程序 以便它还可以 1 在用户单击 选项 单击时放大 缩小球 2 允许您通过按下按钮来选择
  • 矩阵求逆的最快方法

    我想用反函数和很多函数处理图像 为了让代码快速运行 有谁能在 3 种反转方法中建议一种快速方法吗 double cvInvert const CvArr src CvArr dst int method CV LU CV LU 高斯消除并选
  • 如何将天数添加到字符串数据类型的 jtextfield 中给出的日期

    再会 我只是想问一下在给定日期中添加天数 我有一个 jtexfield txtStart 和另一个 jtexfield txtExpiry 我需要在 txtExpiry 中显示距 txtStart 中的日期 102 天后的日期 我正在使用
  • 如何在函数定义和函数调用中使用可变宏参数?

    我正在尝试使用宏根据宏的参数定义几个类似的函数 然而 结果函数需要采用的参数的数量和类型在所有函数中并不相同 但我还需要将函数的所有参数传递到函数体内的另一个可变参数函数中 我想要完成的事情的一个最小例子 define COMMAND CO
  • Checkstyle规则限制根包之间的交互(使用ImportControl?)

    如何创建 Checkstyle 规则来限制不同根包之间的交互 我有以下3个根包 models views controllers They are not就像是com mycompany myproject models 他们是根包 我想禁
  • 如何使用循环获取dir()中的值?

    为什么我无法使用循环获取 dir 中项目的值 for item in dir print item 它只是打印 builtins doc loader name package spec 那么 我如何使用循环来打印 item 中的值 即 m
  • Scala 中的 N 皇后

    def queens n Int List List Int Int def placeQueens k Int List List Int Int if k 0 List List else for queens lt placeQuee