我已经在课程上提交了我的scala作业,但似乎有些考试失败了:
Your solution achieved a testing score of 70 out of 110.
Below you can see a short feedback for every test that failed, indicating the reason
for the test failure and how many points you lost for each individual test.
[Test Description] filter: tweet with 321 retweets
[Observed Error] Test timeout: aborted after 40 seconds; Check for infinite loops!
[exception was thrown] detailed error message in debug output section below
[Lost Points] 10
[Test Description] filter and union: tweets with 321 and 205 retweets
[Observed Error] Test timeout: aborted after 40 seconds; Check for infinite loops!
[exception was thrown] detailed error message in debug output section below
[Lost Points] 10
[Test Description] filter and trending: tweets with 321 and 205 retweets
[Observed Error] Test timeout: aborted after 40 seconds; Check for infinite loops!
[exception was thrown] detailed error message in debug output section below
[Lost Points] 10
[Test Description] trending: google and apple tweets
[Observed Error] Test timeout: aborted after 40 seconds; Check for infinite loops!
[exception was thrown] detailed error message in debug output section below
[Lost Points] 10
我的问题是我无法想象我的功能失败的任何情况。通过分配提供的标准测试没有问题。
这是过滤器和联合功能:
def union(that: TweetSet): TweetSet = (left.union(right)).union(that).incl(elem)
val isEmpty = false
def filter(p: Tweet => Boolean): TweetSet = filterAcc(p,new Empty)
def filterAcc(p: Tweet => Boolean, acc: TweetSet): TweetSet = {
if(left.isEmpty && right.isEmpty) acc
else if(p(elem)){ left.filterAcc(p,acc.incl(elem)).union(right.filterAcc(p,acc.incl(elem)))}
else left.filterAcc(p,acc).union(right.filterAcc(p,acc))
}
如果有人需要它以获得更好的调试,那么这是完整的代码:
package objsets
import common._
import TweetReader._
/**
* A class to represent tweets.
*/
class Tweet(val user: String, val text: String, val retweets: Int) {
override def toString: String =
"User: " + user + "\n" +
"Text: " + text + " [" + retweets + "]"
}
/**
* This represents a set of objects of type `Tweet` in the form of a binary search
* tree. Every branch in the tree has two children (two `TweetSet`s). There is an
* invariant which always holds: for every branch `b`, all elements in the left
* subtree are smaller than the tweet at `b`. The eleemnts in the right subtree are
* larger.
*
* Note that the above structure requires us to be able to compare two tweets (we
* need to be able to say which of two tweets is larger, or if they are equal). In
* this implementation, the equality / order of tweets is based on the tweet's text
* (see `def incl`). Hence, a `TweetSet` could not contain two tweets with the same
* text from different users.
*
*
* The advantage of representing sets as binary search trees is that the elements
* of the set can be found quickly. If you want to learn more you can take a look
* at the Wikipedia page [1], but this is not necessary in order to solve this
* assignment.
*
* [1] http://en.wikipedia.org/wiki/Binary_search_tree
*/
abstract class TweetSet {
def greatestCurrent(soFar: Tweet):Tweet
def iterateAndAddList(list: TweetList): TweetList
def isEmpty: Boolean
/**
* This method takes a predicate and returns a subset of all the elements
* in the original set for which the predicate is true.
*
* Question: Can we implment this method here, or should it remain abstract
* and be implemented in the subclasses?
*/
def filter(p: Tweet => Boolean): TweetSet
/**
* This is a helper method for `filter` that propagetes the accumulated tweets.
*/
def filterAcc(p: Tweet => Boolean, acc: TweetSet): TweetSet
/**
* Returns a new `TweetSet` that is the union of `TweetSet`s `this` and `that`.
*
* Question: Should we implment this method here, or should it remain abstract
* and be implemented in the subclasses?
*/
def union(that: TweetSet): TweetSet;
/**
* Returns the tweet from this set which has the greatest retweet count.
*
* Calling `mostRetweeted` on an empty set should throw an exception of
* type `java.util.NoSuchElementException`.
*
* Question: Should we implment this method here, or should it remain abstract
* and be implemented in the subclasses?
*/
def mostRetweeted: Tweet = ???
/**
* Returns a list containing all tweets of this set, sorted by retweet count
* in descending order. In other words, the head of the resulting list should
* have the highest retweet count.
*
* Hint: the method `remove` on TweetSet will be very useful.
* Question: Should we implment this method here, or should it remain abstract
* and be implemented in the subclasses?
*/
def descendingByRetweet: TweetList
/**
* The following methods are already implemented
*/
/**
* Returns a new `TweetSet` which contains all elements of this set, and the
* the new element `tweet` in case it does not already exist in this set.
*
* If `this.contains(tweet)`, the current set is returned.
*/
def incl(tweet: Tweet): TweetSet
/**
* Returns a new `TweetSet` which excludes `tweet`.
*/
def remove(tweet: Tweet): TweetSet
/**
* Tests if `tweet` exists in this `TweetSet`.
*/
def contains(tweet: Tweet): Boolean
/**
* This method takes a function and applies it to every element in the set.
*/
def foreach(f: Tweet => Unit): Unit
}
class Empty extends TweetSet {
def greatestCurrent(soFar: Tweet):Tweet = new Tweet("a","b",-1)
def iterateAndAddList(list: TweetList): TweetList = list
def descendingByRetweet() = Nil
def union(that: TweetSet): TweetSet = that
def isEmpty = true
def filter(p: Tweet=> Boolean): TweetSet = new Empty()
def filterAcc(p: Tweet => Boolean, acc: TweetSet): TweetSet = new Empty()
/**
* The following methods are already implemented
*/
def contains(tweet: Tweet): Boolean = false
def incl(tweet: Tweet): TweetSet = new NonEmpty(tweet, new Empty, new Empty)
def remove(tweet: Tweet): TweetSet = this
def foreach(f: Tweet => Unit): Unit = ()
}
class NonEmpty(elem: Tweet, left: TweetSet, right: TweetSet) extends TweetSet {
def descendingByRetweet = {
iterateAndAddList(Nil)
}
def iterateAndAddList(list: TweetList): TweetList = {
val current: Tweet = greatestCurrent(new Tweet("a","b",-1))
if(current.retweets != -1){
this.remove(current).iterateAndAddList(list.add(current))
}else list
}
def greatestCurrent(soFar: Tweet):Tweet = {
if(left.isEmpty && right.isEmpty) soFar
else{
if(elem.retweets < soFar.retweets) { mostPopular(left.greatestCurrent(soFar),right.greatestCurrent(soFar)) }
else if(elem.retweets > soFar.retweets){ mostPopular(left.greatestCurrent(elem),right.greatestCurrent(elem)) }
else { mostPopular(left.greatestCurrent(soFar),right.greatestCurrent(soFar)) }
}
}
def mostPopular(left: Tweet,right: Tweet):Tweet = {
if(left.retweets > right.retweets) left
else if(right.retweets > left.retweets) right
else left
}
def union(that: TweetSet): TweetSet = (left.union(right)).union(that).incl(elem)
val isEmpty = false
def filter(p: Tweet => Boolean): TweetSet = filterAcc(p,new Empty)
def filterAcc(p: Tweet => Boolean, acc: TweetSet): TweetSet = {
if(left.isEmpty && right.isEmpty) acc
else if(p(elem)){ left.filterAcc(p,acc.incl(elem)).union(right.filterAcc(p,acc.incl(elem)))}
else left.filterAcc(p,acc).union(right.filterAcc(p,acc))
}
/**
* The following methods are already implemented
*/
def contains(x: Tweet): Boolean =
if (x.text < elem.text) left.contains(x)
else if (elem.text < x.text) right.contains(x)
else true
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
}
def remove(tw: Tweet): TweetSet =
if (tw.text < elem.text) new NonEmpty(elem, left.remove(tw), right)
else if (elem.text < tw.text) new NonEmpty(elem, left, right.remove(tw))
else left.union(right)
def foreach(f: Tweet => Unit): Unit = {
f(elem)
left.foreach(f)
right.foreach(f)
}
}
有人可以向我解释为什么我的代码失败了吗?我不是在寻找烘焙代码,因为这会违反课程荣誉代码。我很感激有关我的代码有什么问题的任何反馈。
注意:随分配提供的标准测试运行正常。问题是提交时。也请不要给我烘焙代码
答案 0 :(得分:1)
你的联盟实施效率太低。它可以很容易地重构,以提高效率。它仍然只能使用union和incl方法的递归调用,但不能按照你的顺序使用。
我怀疑这不是一个真正的无限循环,而是对Coursera测试运行时间过长。这就是为什么你的本地较小的测试用例通过了。