2016-11-25 61 views
0

在这段代码中,我试图采取下列两棵树的工会:#1错误Scala代码

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 
} 

但是,当我尝试执行工会法,我得到的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) 

这是为什么发生?

+0

请问您是否可以将inc方法定义添加到帖子中?和TweetSet – Pavel

+0

添加了代码... – sarthak

+1

您了解inc方法的递归性质吗?这是这个问题的关键。 – Pavel

回答

1

对于递归最终终止,您需要确保unionRec的第一个参数早晚的树是空的。 既然你总是左右调用它,你的递归永远不会终止。

+0

但是如果我递归地拿走了树的左边,它是否最终不会变空并终止? – sarthak

+0

左不会将元素作为unionRec的参数使用。 – Buhb

-2

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

要修复它,你应该重新写它来做尾递归。 Scala将这些类型的递归表示为一个简单的循环。

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