Scala中二叉树的尾递归最大深度方法

2024-01-03

我写了一个计算二叉树最大深度的方法。

我想写一个尾递归方法。

我想过使用列表,但没有找到解决方案

这是我的方法,不是尾递归的:

def depth: Int = {

    def iter(f: FormulaWff): Int = f match {
      case Var(_) => 0
      case Not(e1) => 1 + iter(e1)
      case And(e1, e2)  => 1 + Math.max(iter(e1), iter(e2))
      case Or(e1, e2) => 1 + Math.max(iter(e1), iter(e2))
      case Implies(e1, e2) => 1 + Math.max(iter(e1), iter(e2))
    }

    iter(this)
  }

Try

import scala.util.control.TailCalls.{TailRec, done, tailcall}

trait FormulaWff {
  def depth: Int = {
    def iter(f: FormulaWff): TailRec[Int] = {
      def hlp(e1: FormulaWff, e2: FormulaWff): TailRec[Int] = for {
        x <- tailcall(iter(e1))
        y <- tailcall(iter(e2))
      } yield 1 + Math.max(x, y)

      f match {
        case Var(_) => done(0)
        case Not(e1) => for {
          x <- tailcall(iter(e1))
        } yield 1 + x
        case And(e1, e2) => hlp(e1, e2)
        case Or(e1, e2) => hlp(e1, e2)
        case Implies(e1, e2) => hlp(e1, e2)
      }
    }

    iter(this).result
  }
}

case class Var(s: String) extends FormulaWff
case class Not(e: FormulaWff) extends FormulaWff
case class And(e1: FormulaWff, e2: FormulaWff) extends FormulaWff
case class Or(e1: FormulaWff, e2: FormulaWff) extends FormulaWff
case class Implies(e1: FormulaWff, e2: FormulaWff) extends FormulaWff

直接解决

  sealed trait FormulaWff
  final case class Var(s: String) extends FormulaWff
  final case class Not(e: FormulaWff) extends FormulaWff
  final case class And(e1: FormulaWff, e2: FormulaWff) extends FormulaWff
  final case class Or(e1: FormulaWff, e2: FormulaWff) extends FormulaWff
  final case class Implies(e1: FormulaWff, e2: FormulaWff) extends FormulaWff

  sealed trait Result
  case object NotExpanded extends Result
  case object Expanded extends Result
  final case class Calculated(value: Int) extends Result

  final case class Frame(arg: FormulaWff, res: Result)

  def depth(f: FormulaWff): Int = step1(List(Frame(f, NotExpanded))) match {
    case Frame(arg, Calculated(res)) :: Nil => res
  }

  @tailrec
  def step1(stack: List[Frame]): List[Frame] = {
    val x = step(stack, Nil)
    x match {
      case Frame(arg, Calculated(res)) :: Nil => x
      case _ => step1(x)
    }
  }

  @tailrec
  def step(stack: List[Frame], acc: List[Frame]): List[Frame] = {
    stack match {
      case Frame(_, Calculated(res1)) :: Frame(_, Calculated(res2)) :: Frame(And(e1, e2), Expanded) :: frames =>
        step(frames, Frame(And(e1, e2), Calculated(1 + math.max(res1, res2))) :: acc)
      case Frame(_, Calculated(res1)) :: Frame(_, Calculated(res2)) :: Frame(Or(e1, e2), Expanded) :: frames =>
        step(frames, Frame(Or(e1, e2), Calculated(1 + math.max(res1, res2))) :: acc)
      case Frame(_, Calculated(res1)) :: Frame(_, Calculated(res2)) :: Frame(Implies(e1, e2), Expanded) :: frames =>
        step(frames, Frame(Implies(e1, e2), Calculated(1 + math.max(res1, res2))) :: acc)
      case Frame(_, Calculated(res1)) :: Frame(Not(e1), Expanded) :: frames =>
        step(frames, Frame(Not(e1), Calculated(1 + res1)) :: acc)
      case Frame(Var(s), _) :: frames =>
        step(frames, Frame(Var(s), Calculated(0)) :: acc)

      case Frame(Not(e1), NotExpanded) :: frames =>
        step(frames, Frame(Not(e1), Expanded) :: Frame(e1, NotExpanded) :: acc)
      case Frame(And(e1, e2), NotExpanded) :: frames =>
        step(frames, Frame(And(e1, e2), Expanded) :: Frame(e1, NotExpanded) :: Frame(e2, NotExpanded) :: acc)
      case Frame(Or(e1, e2), NotExpanded) :: frames =>
        step(frames, Frame(Or(e1, e2), Expanded) :: Frame(e1, NotExpanded) :: Frame(e2, NotExpanded) :: acc)
      case Frame(Implies(e1, e2), NotExpanded) :: frames =>
        step(frames, Frame(Implies(e1, e2), Expanded) :: Frame(e1, NotExpanded) :: Frame(e2, NotExpanded) :: acc)

      case Frame(arg, Expanded) :: frames => step(frames, Frame(arg, Expanded) :: acc)
      case Frame(arg, Calculated(res)) :: frames => step(frames, Frame(arg, Calculated(res)) :: acc)

      case Nil => acc.reverse
    }
  }

如何使树映射尾递归? https://stackoverflow.com/questions/55042834/how-to-make-tree-mapping-tail-recursive

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

Scala中二叉树的尾递归最大深度方法 的相关文章

随机推荐

  • .onload 从 Firefox 扩展调用多次

    我正在开发一个 Firefox 扩展并具有以下代码 function initialize For accessing browser window from sidebar code var mainWindow window Query
  • IE 中的事件处理

    我下面包含的代码允许我在用户第一次将鼠标悬停在元素上时执行某些操作 然后删除该事件 它在 W3C 事件模型浏览器中运行良好 但在 IE6 8 中不断抛出错误 我从另一个问题中得到了代码 并相信它可以处理 IE 有人看到我做错了什么吗
  • 如何使用 Tesseract OCR 从图像中读取表格数据?

    有谁知道如何从图像中读取和解析任何表格数据 我正在使用 asp net 应用程序 并且已使用 Tesseract OCR API 成功读取数据 但无法从图像读取表格 请用c 代码给出解决方案 None
  • 在 div 上使用 .FindControl() 失败

    我有一个 html div 元素 其中包含多个 div 其值我想放入数组服务器端 我的 html div 看起来像 div div class box 2 div div class box 1 div div class box 3 di
  • jQuery:如何找到第一个可见的输入/选择/文本区域(不包括按钮)?

    I tried input not input type button input type submit button visible first 但它没有找到任何东西 我的错误是什么 UPD 我在 document load 上执行此操
  • Python循环遍历Excel表格,放入一个df中

    我有一个 Excel 文件foo xlsx约40张sh1 sh2等 每张纸的格式为 area cnt name nparty1 name nparty2 blah 9 5 5 word 3 7 5 在每张表中 我想用以下格式重命名变量nam
  • 比特币地址生成出现Python错误

    我正在尝试用 python 来理解比特币 并尝试创建我自己的虚荣地址生成器 下面是 while 循环的片段 循环运行大约 10 次后 我不断收到错误消息 任何帮助将不胜感激 我搜索了论坛并找到了答案 但它们不起作用 IE 我改变了 inte
  • XP 和 Server 2003 上并发调用时 wmic 失败

    我在用wmic以获得时间 我已将其范围缩小到一 1 行 bat 文件 我从 stackoverflow 学到了有关管道 stdin 和 stdout 以避免挂起的知识 C gt type t bat TYPE NUL wmic os get
  • ASP.Net 3.5/4.0 代码隐藏还是代码文件?

    我读了之前的帖子 代码文件与代码隐藏 https stackoverflow com questions 73022 codefile vs codebehind 但我仍然很困惑应该使用哪个 听起来 CodeFile 是应该使用的较新选项
  • 创建一系列文本剪辑并使用 moviepy 将它们连接成视频

    在 MoviePy 中 有一个 API 可以从文本创建剪辑以及连接剪辑列表 我正在尝试在循环中创建剪辑列表 然后尝试将它们连接起来 问题是每次它都会创建一个 25 秒的视频文件 并且循环中仅包含最后一个文本 这是代码 for text in
  • 如何在没有原型的情况下找到C函数?

    公司政策规定 C 源代码中的每个函数都有一个原型 我继承了一个有自己的 make 系统的项目 所以我cannot在 gcc 或 Visual Studio 上测试它 发现其中一个文件有一些没有原型声明的静态函数 有没有办法 不一定使用编译器
  • 如何在Android上将GPS坐标保存在exif数据中?

    我正在将 GPS 坐标写入 JPEG 图像 并且坐标是正确的 如我的 logcat 输出所示 但它似乎以某种方式被损坏 读取 exif 数据会导致空值 或者对于我的 GPS 512 976698 degrees 512 976698 deg
  • 使用 VBA 从 Outlook 2010 保存 .XLSX 附件

    我们使用 Outlook 2010 并接收带有 Excel 附件的电子邮件 我们手动将附件保存在我们在网络驱动器上的分区文件夹中创建的子文件夹中 我很好奇的是是否有可能 使用代码检查传入的电子邮件以查看它们是否有附件 然后检查附件是否为 X
  • 内存间接寻址 movl - 汇编

    我试图了解内存间接寻址在具有 AT T 语法的汇编语言中到底是如何工作的 movl eax ebx movl eax ebx 这是一个类似的问题 解释了内存间接寻址 https stackoverflow com questions 161
  • 是否可以使 JavaFX 中的 ImageView 响应式?

    我和一些朋友正在进行一个项目 我们尝试用 JavaFX 编写游戏 我们有一个 GridPane 它与内部的 ImageView 一起生长以容纳地图和游戏角色等 游戏角色和敌人将有自己的图像视图 我们可以在网格窗格中移动 所以 我们现在的问题
  • 尝试禁用 JInternalFrame 的拖动

    我已经四处寻找了一段时间 但找不到禁用拖动 JIntenal Frame 的方法 任何帮助将不胜感激 TYIA 罗兰 请记住这是一个小程序 import java awt import java applet import java awt
  • 如何查询NHibernate的特定类型?

    我使用 Fluent NHibernate 和 DiscrimminateSubClassesOnColumn 来支持子类化 用于区分子类的列未映射到实体上的实际属性 如何创建仅返回给定类型实体的查询 这是我的尝试 其中 propertyN
  • ESP8266 在简单的 http 请求后崩溃

    我正在使用 NodeMCU V3 模块 每当我尝试向服务器发出 http 请求时 模块就会崩溃 这是代码 void setup WiFi begin wifi name wifi password while WiFi status WL
  • 无法从 ruby​​gems 下载数据

    我不知道尝试运行时这个错误意味着什么gem update system 9 29 2 2 3 gem update system ERROR While executing gem Gem RemoteFetcher FetchError
  • Scala中二叉树的尾递归最大深度方法

    我写了一个计算二叉树最大深度的方法 我想写一个尾递归方法 我想过使用列表 但没有找到解决方案 这是我的方法 不是尾递归的 def depth Int def iter f FormulaWff Int f match case Var gt