【问题标题】:Stackoverflow error in scala codeScala代码中的Stackoverflow错误
【发布时间】:2016-11-26 01:33:23
【问题描述】:

在这段代码中,我试图将两棵树合并如下:

class NonEmpty(elem: Tweet, left: TweetSet, right: TweetSet) extends TweetSet {

    def union(that: TweetSet): TweetSet =
    {
      def unionRec(set:TweetSet,acc:TweetSet): TweetSet =
      {
        if (set.isEmpty)
          return acc
        else
          return unionRec(right,unionRec(left,acc.incl(elem)))
      }
      unionRec(this,that)
    }

    def isEmpty: Boolean = false

    def incl(x: Tweet): TweetSet = {
      if (x.text < elem.text) new NonEmpty(elem, left.incl(x), right)
      else if (elem.text < x.text) new NonEmpty(elem, left, right.incl(x))
      else this
    }

}

class Empty extends TweetSet {
  def isEmpty: Boolean = true
}

但是当我尝试执行 union 方法时,我得到了 stackOverflow 错误:

java.lang.StackOverflowError
    at scala.collection.immutable.StringLike$class.compare(StringLike.scala:74)
    at scala.collection.immutable.StringOps.compare(StringOps.scala:30)
    at scala.collection.immutable.StringOps.compare(StringOps.scala:30)
    at scala.math.Ordered$class.$less(Ordered.scala:76)
    at scala.collection.immutable.StringOps.$less(StringOps.scala:30)
    at objsets.NonEmpty.incl(TweetSet.scala:235)
    at objsets.NonEmpty.incl(TweetSet.scala:236)
    at objsets.NonEmpty.incl(TweetSet.scala:235)
    at objsets.NonEmpty.incl(TweetSet.scala:236)
    at objsets.NonEmpty.incl(TweetSet.scala:235)
    at objsets.NonEmpty.incl(TweetSet.scala:235)
    at objsets.NonEmpty.incl(TweetSet.scala:236)
    at objsets.NonEmpty.incl(TweetSet.scala:236)
    at objsets.NonEmpty.incl(TweetSet.scala:235)

为什么会这样?

【问题讨论】:

  • 能否请您也将 inc 方法定义添加到帖子中?和推文集
  • 添加了代码...
  • 你了解 inc 方法的递归性质吗?这是解决这个问题的关键。
  • 如果您可以访问 coursera 数学。尝试阅读相关主题。
  • 考虑这一行:if (x.text &lt; elem.text) new NonEmpty(elem, left.incl(x), right)。当left 为空时,会发生什么?

标签: scala


【解决方案1】:

为了使递归最终终止,您需要确保 unionRec 的第一个参数中的树迟早是空的。 由于您总是用左右调用它,因此您的递归永远不会终止。

【讨论】:

  • 但是如果我递归地取树的左边,它最终不会变空并终止吗?
  • Left 不会因为用作 unionRec 的参数而丢失元素。
【解决方案2】:

你有unionRec 方法女巫是递归的。显然它调用自己的次数太多,实际上是导致堆栈溢出。

要修复它,您应该重新编写它以进行尾递归。 Scala 将这种递归表示为一个简单的循环。

使用@tailrec 注释来注释您的方法,以确保它满足尾递归要求。

【讨论】:

    猜你喜欢
    • 2016-03-15
    • 1970-01-01
    • 1970-01-01
    • 2021-12-13
    • 1970-01-01
    • 2012-07-26
    • 1970-01-01
    • 2020-05-28
    • 1970-01-01
    相关资源
    最近更新 更多