滤波器算法中缺少逻辑
我正在尝试从课程
scala课程中解决第三项任务.我已经完成了一些但是我认为在某个特定功能方面我忽略了这一点.我必须实现过滤器函数,该函数将返回给定满足给定谓词的推文集中的所有推文的子集.我已经实现了一些我认为可以帮助我的功能,但测试失败了
注意请不要给我烘焙代码,因为这将违反课程荣誉代码.我想要的只是帮助我调试逻辑并帮助我查看我搞砸的地方以及测试失败的原因. abstract class TweetSet { 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 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 union(that: TweetSet): TweetSet = (left.union(right)).union(that).incl(elem) val isEmpty = false def filter(p: Tweet => Boolean): TweetSet = filterAcc(p,left.union(right)) def filterAcc(p: Tweet => Boolean,acc: TweetSet): TweetSet = { if(acc.isEmpty) acc else if(p(elem)) {acc.incl(elem); left.filterAcc(p,acc).union(right.filterAcc(p,acc))} else new Empty } /** * 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,right.remove(tw)) else left.union(right) def foreach(f: Tweet => Unit): Unit = { f(elem) left.foreach(f) right.foreach(f) } } 我认为关于这一点的主要错误是filterAcc,因为当没有任何情况适用时它返回空,但是我不确定我还能做什么.一切都失败了吗?如果是的话我应该怎么回事呢? UPDATE def filterAcc(p: Tweet => Boolean,acc))} else left.filterAcc(p,acc)) } 此方法现在确保如果没有匹配条件,则仍然进行递归调用,但同时累加器不会增加.测试仍然失败.我逻辑的缺陷是什么? 谢谢 正如@lpiepiora和@Ende Neu拼命试图告诉我的那样,acc的开头应该是空的.我最终仍然使用了一个联盟,因为我的思绪只是堆积了这个想法而我无法理解它.这是最后一段代码: 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)) } 解决方法
这对我来说也非常棘手.
你的方法中的一个问题是你没有正确使用累加器,事实上你正在传递集合联合,一个累加器应该只存储与给定谓词p匹配的结果,因为你可以在for或中使用累加器while循环时,应将其初始化为起始值(例如,对于Int 0,对于String,为空字符串,依此类推). 例如,假设您有一个List [Int],并且您想要计算正整数的数量: val list = List(0,-1,-2,4,9,-7) def countPositive(list: List[Int]): Int = { def loop(list: List[Int],acc: Int): Int = list match { case Nil => acc case head :: tail => { if( head > 0) loop(tail,acc + 1) else loop(tail,acc) } } loop(list,0) } 例如,此累加器的起始值为0,filterAcc函数中的累加器应使用相同的方法. 你要做的是拥有一个集合的联合,然后将它们用作可以迭代的标准集合,我想问题的关键是要处理像这样的全功能数据结构,那就是没有集合集合但是一堆以某种方式连接的对象.如果你还记得在讲座3.1大约7.20附近的视频,那么Odersky显示的部分包含和包含操作不会修改三个结构,而是创建一个新结构,我的理解是这就是问题的精神. 回到代码,您可以将其视为可以递归的集合,我的方法是使用自定义尾部和头部函数,如果尾部存在,您可以继续迭代到下一个对象并添加满足谓词的头元素累加器.每次迭代时都会创建一个新的三个结构,避开已经检查过的部分,使用isEmpty方法确实知道NonEmpty是左边还是三个. 请注意,这个方法(尾部和头部)可以(在我的实现中)是递归的,非常棘手的部分是tail总是返回新的三个对象(如Odersky定义纯粹功能的结构时在视频上所示). 我可以给出的另一个建议是尝试使用自下而上的策略,总是使用left.isEmpty(或right.isEmpty)递归到左边(或右边)的最后一个元素来检查三个结束的位置,检查你是否必须使用head将元素添加到累加器中,然后构建一个新的三元素,而不使用tail检查元素. 这对我来说非常棘手,我不知道我是否正确地解释了自己,或者这是否足以让你开始,不幸的是对于像我这样对纯粹功能数据结构的经验很少的人很难在不显示代码的情况下解释它,祝好运. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- Angular 2 –aot导致AnimationEntryMetadata失败
- Bootstrap学习8--代码
- Angular2学习笔记(三) Angular2 数据显示
- angularjs – 如何使用gitlab-ci-multi-runner在GitLab CI中
- 数组 – 如何使用ngFor Angular 2在对象数组中显示数组
- cxf动态调用webservice设置超时,测试线程安全
- angularjs – Angular UI / select2多个如何预选值/选项?
- 关于webservice在本机上能够运行,在设备上不行的原因
- AngularJS,解析和未知提供者
- scala – Lift中MegaProtoUser的替代品