Functional Programming Principles in Scala 
by Martin Odersky

这次的作业叫做Object-Oriented Sets。要完成一个完整的类,实现取最大值、排序等方法。由于是函数式编程,这些的实现方法和以往我知道的完全不一样。

总结

TweetSet有两个子类,Empty和NonEmpty,使用BFT实现。有一点比较惊奇的是父类的方法可以创建一个子类的对象,以往并没有认识到这一点。
在方法的实现上,filter和mostRetweeted都需要使用辅助方法(acc)来做递归。
类似于contains的实现方法,很巧妙的对类进行了遍历。
有的方法需要在两个子类里面以不同的方法实现。对于把一个类分成父类和两个子类这一点,我的感觉是为了最大程度的把子类的公共部分抽象出来,杀鸡用了牛刀。
我的实现里面,mostRetweeted调用了mostAcc,同时传递了一个新建的Tweet。为了更优美应该分别在两个子类里面实现。
程序优化很少,感觉运行效率很低,很奇怪有些公司用scala来运营网站等。
我的程序
package objsetsimport 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 {/*** 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 = filterAcc(p,new Empty())/*** 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 = filterAcc(x => this.contains(x),that.filterAcc(x=>that.contains(x),new Empty()))/*** 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=mostAcc(new Tweet("tmp","tmp",0))def mostAcc(tmp:Tweet):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 filterAcc(p: Tweet => Boolean, acc: TweetSet): TweetSet = accdef mostAcc(tmp:Tweet):Tweet=tmpdef descendingByRetweet: TweetList = Nil/*** The following methods are already implemented*/def contains(tweet: Tweet): Boolean = falsedef incl(tweet: Tweet): TweetSet = new NonEmpty(tweet, new Empty, new Empty)def remove(tweet: Tweet): TweetSet = thisdef foreach(f: Tweet => Unit): Unit = ()
}class NonEmpty(elem: Tweet, left: TweetSet, right: TweetSet) extends TweetSet {def filterAcc(p: Tweet => Boolean, acc: TweetSet): TweetSet = {if (p(elem)) right.filterAcc(p,left.filterAcc(p,acc.incl(elem)))else right.filterAcc(p,left.filterAcc(p,acc))}def mostAcc(tmp:Tweet):Tweet={if (tmp.retweets>elem.retweets) right.mostAcc(left.mostAcc(tmp))else right.mostAcc(left.mostAcc(elem))}def descendingByRetweet: TweetList = {new Cons(this.mostRetweeted,this.remove(this.mostRetweeted).descendingByRetweet)}/*** 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 truedef 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)}
}trait TweetList {def head: Tweetdef tail: TweetListdef isEmpty: Booleandef foreach(f: Tweet => Unit): Unit =if (!isEmpty) {f(head)tail.foreach(f)}
}object Nil extends TweetList {def head = throw new java.util.NoSuchElementException("head of EmptyList")def tail = throw new java.util.NoSuchElementException("tail of EmptyList")def isEmpty = true
}class Cons(val head: Tweet, val tail: TweetList) extends TweetList {def isEmpty = false
}object GoogleVsApple {val google = List("android", "Android", "galaxy", "Galaxy", "nexus", "Nexus")val apple = List("ios", "iOS", "iphone", "iPhone", "ipad", "iPad")lazy val googleTweets: TweetSet = TweetReader.allTweets.filter(y=>google.exists( x => y.text.contains(x)))lazy val appleTweets: TweetSet = TweetReader.allTweets.filter(y=>apple.exists( x => y.text.contains(x)))/*** A list of all tweets mentioning a keyword from either apple or google,* sorted by the number of retweets.*/lazy val trending: TweetList = googleTweets.union(appleTweets).descendingByRetweet
}object Main extends App {// Print the trending tweetsGoogleVsApple.trending foreach println
}

题目要求

Download the objsets.zip handout archive file.In this assignment you will work with an object-oriented representations based on binary trees.Object-Oriented Sets
For this part, you will earn credit by completing the TweetSet.scala file. This file defines an abstract class TweetSet with two concrete subclasses, Empty which represents an empty set, and NonEmpty(elem: Tweet, left: TweetSet, right: TweetSet), which represents a non-empty set as a binary tree rooted at elem. The tweets are indexed by their text bodies: the bodies of all tweets on the left are lexicographically smaller than elem and all bodies of elements on the right are lexicographically greater.Note also that these classes are immutable: the set-theoretic operations do not modify this but should return a new set.Before tackling this assignment, we suggest you first study the already implemented methods contains and incl for inspiration.1 Filtering
Implement filtering on tweet sets. Complete the stubs for the methods filter and filterAcc. filter takes as argument a function, the predicate, which takes a tweet and returns a boolean. filter then returns the subset of all the tweets in the original set for which the predicate is true. For example, the following call:tweets.filter(tweet => tweet.retweets > 10)
applied to a set tweets of two tweets, say, where the first tweet was not retweeted and the second tweet was retweeted 20 times should return a set containing only the second tweet.Hint: start by defining the helper method filterAcc which takes an accumulator set as a second argument. This accumulator contains the ongoing result of the filtering./** This method takes a predicate and returns a subset of all the elements*  in the original set for which the predicate is true.*/
def filter(p: Tweet => Boolean): TweetSet
def filterAcc(p: Tweet => Boolean, acc: TweetSet): TweetSet
The definition of filter in terms of filterAcc should then be straightforward.2 Taking Unions
Implement union on tweet sets. Complete the stub for the method union. The method union takes another set that, and computes a new set which is the union of this and that, i.e. a set that contains exactly the elements that are either in this or in that, or in both.def union(that: TweetSet): TweetSet
Note that in this exercise it is your task to find out in which class(es) to define the union method (should it be abstract in class TweetSet?).3 Sorting Tweets by Their Influence
The more often a tweet is “re-tweeted” (that is, repeated by a different user with or without additions), the more influential it is.The goal of this part of the exercise is to add a method descendingByRetweet to TweetSet which should produce a linear sequence of tweets (as an instance of class TweetList), ordered by their number of retweets:def descendingByRetweet: TweetList
This method reflects a common pattern when transforming data structures. While traversing one data structure (in this case, a TweetSet), we’re building a second data structure (here, an instance of class TweetList). The idea is to start with the empty list Nil (containing no tweets), and to find the tweet with the most retweets in the input TweetSet. This tweet is removed from the TweetSet (that is, we obtain a new TweetSet that has all the tweets of the original set except for the tweet that was “removed”; this immutable set operation, remove, is already implemented for you), and added to the result list by creating a new Cons. After that, the process repeats itself, but now we are searching through a TweetSet with one less tweet.Hint: start by implementing the method mostRetweeted which returns the most popular tweet of a TweetSet.4 Tying everything together
In the last step of this assignment your task is to detect influential tweets in a set of recent tweets. We are providing you with a TweetSet containing several hundred tweets from popular tech news sites in the past few days, located in the TweetReader object (file “TweetReader.scala”). TweetReader.allTweets returns an instance of TweetSet containing a set of all available tweets.Furthermore, you are given two lists of keywords. The first list corresponds to keywords associated with Google and Android smartphones, while the second list corresponds to keywords associated with Apple and iOS devices. Your objective is to detect which platform has generated more interest or activity in the past few days.As a first step, use the functionality you implemented in the first parts of this assignment to create two different TweetSets, googleTweets and appleTweets. The first TweetSet, googleTweets, should contain all tweets that mention (in their “text”) one of the keywords in the google list. The second TweetSet, appleTweets, should contain all tweets that mention one of the keyword in the apple list. Their signature is as follows:lazy val googleTweets: TweetSet
lazy val appleTweets: TweetSet
Hint: use the exists method of List and contains method of class java.lang.String.From the union of those two TweetSets, produce trending, an instance of class TweetList representing a sequence of tweets ordered by their number of retweets:lazy val trending: TweetList

Martin Odersky Scala编程公开课 第三周作业相关推荐

  1. Martin Odersky Scala编程公开课 第二周作业

    Functional Programming Principles in Scala  by Martin Odersky 这一周的主要内容是函数.函数是scala语言最重要的概念,既可以当作函数的参 ...

  2. Martin Odersky Scala编程公开课 第一周作业

    Functional Programming Principles in Scala  by Martin Odersky Martin教授是scala语言的creator,在coursera上面有s ...

  3. 佐治亚理工学院 计算投资公开课第六周作业 投资策略分析平台

    策略分析平台 在前两周的工作中,实现了股票价格低于门限值这一策略的event study,即根据门限值来看事件发生前后股票的价格.同时,完成了根据下单的指令来进行回测,计算策略执行期间每一天的价值,以 ...

  4. 佐治亚理工学院 计算投资公开课第五周作业 市场仿真器

    Computational Investing, Part I  by Dr. Tucker Balch 这门课的讲授者给出了一个开源的python包QuantSoftware ToolKit,方便教 ...

  5. SAP Fiori Elements 公开课第三单元学习笔记 - OData 和注解深入讲解

    课程地址 很多 SAP 从业者反映,open SAP 上的视频,因为网络原因无法访问,所以我会陆续在我的个人微 信 号"汪子熙"上面,把这些视频配上中文字幕并发布出来,敬请关注. ...

  6. triz矛盾矩阵_TRIZ 创新方法 培训 之TRIZ 公开课 大纲 三天 班

    关于TRIZ创新方法培训的十个典型的错误是什么,Triz培训在市场营销领域创新中如何运用,TRIZ理论的定义.核心思想.主要内容和体系架构.学习本门课程有哪些好处等问题,听听天行健TRIZ创新技术管理 ...

  7. 【中文】【吴恩达课后编程作业】Course 5 - 序列模型 - 第三周作业 - 机器翻译与触发词检测

    [中文][吴恩达课后编程作业]Course 5 - 序列模型 - 第三周作业 - 机器翻译与触发词检测 上一篇:[课程5 - 第三周测验]※※※※※ [回到目录]※※※※※下一篇:无 致谢: 感谢@e ...

  8. 【中文】【吴恩达课后编程作业】Course 2 - 改善深层神经网络 - 第三周作业

    [中文][吴恩达课后编程作业]Course 2 - 改善深层神经网络 - 第三周作业 - TensorFlow入门 上一篇: [课程2 - 第三周测验]※※※※※ [回到目录]※※※※※下一篇: [课 ...

  9. 2017-2018-1 JAVA实验站 第三周作业

    2017-2018-1 JAVA实验站 第三周作业 团队展示 队名 JAVA实验站 拟作的团队项目描述 (2048)增加其他模式,使得2048更加丰富多彩 团队的首次合照 团队的特色描述 团队内部很团 ...

最新文章

  1. SQL Server优化50法
  2. TensorFlow学习笔记(1):variable与get_variable, name_scope()和variable_scope()
  3. 51单片机下载完程序后不亮_程序如何下载到单片机中?单片机常用的四种烧写程序方式介绍...
  4. mysql插入10万测试_[原创]java使用JDBC向MySQL数据库批次插入10W条数据测试效率
  5. 文件同步服务器,iis 集群 ,代码同步(一)
  6. 大学生在校期间可以考哪些证书?
  7. SQL Server 2008 Service Broker
  8. C++学习记录7:定义教师类Teacher和干部类Cadre,采用多重继承的方式由这两个类派生出新类Teacher_Cadre(教师兼干部类)
  9. 《Java编程十五讲》第十一讲:脚本
  10. java 中的连接超时_【java中处理http连接超时的方法】
  11. C++ Qt 05:Qt布局管理器 - 荒 木 - 博客园
  12. 出海日报|巴西电动滑板车Grin与“巴西小黄车” Yellow合并了;印度OYO Rooms要花5000万美元发展菲律宾市场...
  13. Web two days
  14. 使用fastdb的感受
  15. uniapp文字穿插表情消息处理
  16. 在Linux下安装Docker并搭建Eclipse che容器
  17. Javascript——下载功能,获取电脑桌面制定下载路径
  18. OSChina 周六乱弹 ——单身程序员怎么回复漂亮妹子的悲伤心情
  19. 姓名学中五格的算法与吉凶
  20. php微信开放平台获取openid,微信公众平台获取openid

热门文章

  1. python中列表和集合的区别_python中列表和集合有什么区别
  2. 【mysql基础知识】通过Navicat控制小数点位数,以及填充0后不显示的问题
  3. java swing 实现下拉列表点击事件
  4. C语言实现1~100的和(三种循环)
  5. 在微型计算机控制系统中常用的报警方式中,微机控制技术复习题
  6. 普通路由器改4g路由器_4G宽带随心用,办公娱乐更自由,蒲公英X4C路由器体验|路由器|蒲公英|宽带|wifi|sim...
  7. 如何使用线程完成售票系统
  8. java 云笔记本_java版云笔记(五)
  9. python装饰器class_PYTHON里的装饰器能装饰类吗
  10. cast函数_关闭RTTI后dynamic_cast和typeid报异常