2016-11-25 77 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註釋標註您的方法,以確保它滿足尾遞歸要求。