scala习题(14)——模式匹配和样例类
2016-03-13 15:39
447 查看
14.1 JDK发行包有一个src.zip文件包含了JDK的大多数源代码。解压并搜索样例标签(用正则表达式case [^:]+:)。然后查找以//开头并包含[Ff]alls?thr的注释,捕获类似// Falls through或// just fall thru这样的注释。假定JDK的程序员们遵守Java编码习惯,在该写注释的地方写下了这些注释,有多少百分比的样例是会掉入到下一个分支的?
没看懂=。=
14.2 利用模式匹配,编写一个swap函数,接受一个整数的对偶,返回对偶的两个组成部件互换位置的新对偶
偏函数的用法,在使用时可以制定参数类型
14.3 利用模式匹配,编写一个swap函数,交换数组中的前两个元素的位置,前提条件是数组长度至少为2
数组匹配,剩余所有参数的表示方式为_*,用变量名称代替的方式为ar @_*
14.4 添加一个样例类Multiple,作为Item的子类。举例来说,Multiple(10,Article(“Blackwell Toster”,29.95))描述的是10个烤面包机。当然了,你应该可以在第二个参数的位置接受任何Item,无论是Bundle还是另一个Multiple。扩展price函数以应对新的样例。
14.5 我们可以用列表制作只在叶子节点存放值的树。举例来说,列表((3 8) 2 (5))描述的是如下这样一棵树:
*
/ | \
* 2 *
/ \ |
3 8 5
不过,有些列表元素是数字,而另一些是列表。在Scala中,你不能拥有异构的列表,因此你必须使用List[Any]。编写一个leafSum函数,计算所有叶子节点中的元素之和,用模式匹配来区分数字和列表。
14.6 制作这样的树更好的做法是使用样例类。我们不妨从二叉树开始。
sealed abstract class BinaryTree
case class Leaf(value : Int) extends BinaryTree
case class Node(left : BinaryTree,right : BinaryTree) extends BinaryTree
编写一个函数计算所有叶子节点中的元素之和。
使用样例类建议使用密封类的形式,代表本类只在本文件内可见
14.7 扩展前一个练习中的树,使得每个节点可以有任意多的后代,并重新实现leafSum函数。第五题中的树应该能够通过下述代码表示:
14.8 扩展前一个练习中的树,使得每个非叶子节点除了后代之外,能够存放一个操作符。然后编写一个eval函数来计算它的值。举例来说:
+
/ | \
* 2 -
/ \ |
3 8 5
上面这棵树的值为(3 * 8) + 2 + (-5) = 21
14.9 编写一个函数,计算List[Option[Int]]中所有非None值之和。不得使用match语句。
14.10 编写一个函数,将两个类型为Double=>Option[Double]的函数组合在一起,产生另一个同样类型的函数。如果其中一个函数返回None,则组合函数也应返回None。例如:
没看懂=。=
14.2 利用模式匹配,编写一个swap函数,接受一个整数的对偶,返回对偶的两个组成部件互换位置的新对偶
偏函数的用法,在使用时可以制定参数类型
def swap[W,Y](tup:(W,Y))={ tup match{ case (a,b) => (b,a); } }
14.3 利用模式匹配,编写一个swap函数,交换数组中的前两个元素的位置,前提条件是数组长度至少为2
数组匹配,剩余所有参数的表示方式为_*,用变量名称代替的方式为ar @_*
def swap(arr:Array[Int])={ arr match{ case Array(a,b,ar@_*) => Array(b,a,ar); } }
14.4 添加一个样例类Multiple,作为Item的子类。举例来说,Multiple(10,Article(“Blackwell Toster”,29.95))描述的是10个烤面包机。当然了,你应该可以在第二个参数的位置接受任何Item,无论是Bundle还是另一个Multiple。扩展price函数以应对新的样例。
abstract class item; case class Article(description:String,price:Double) extends item; case class Bundle(description:String,discount:Double,items:item*) extends item; case class Multiple(count:Int,item :item) extends item; def price(it:item):Double = it match{ case Article(_,p)=>p; case Bundle(_,disc,its @ _ *)=>its.map(price).sum -disc; case Multiple(count,it) => price(it)*count; }
14.5 我们可以用列表制作只在叶子节点存放值的树。举例来说,列表((3 8) 2 (5))描述的是如下这样一棵树:
*
/ | \
* 2 *
/ \ |
3 8 5
不过,有些列表元素是数字,而另一些是列表。在Scala中,你不能拥有异构的列表,因此你必须使用List[Any]。编写一个leafSum函数,计算所有叶子节点中的元素之和,用模式匹配来区分数字和列表。
def LeafSum(li:List[Any]):Int={ var sum=0; li.foreach{ l => l match{ case list:< 4000 span class="hljs-keyword">List[Any] => sum=sum+LeafSum(list); case t:Int=>sum=sum+t; } } sum; } println(LeafSum(List(List(3,8),2,List(5))));
14.6 制作这样的树更好的做法是使用样例类。我们不妨从二叉树开始。
sealed abstract class BinaryTree
case class Leaf(value : Int) extends BinaryTree
case class Node(left : BinaryTree,right : BinaryTree) extends BinaryTree
编写一个函数计算所有叶子节点中的元素之和。
使用样例类建议使用密封类的形式,代表本类只在本文件内可见
sealed abstract class BinaryTree; case class Leaf(value:Int) extends BinaryTree; case class Node(left:BinaryTree,right:BinaryTree) extends BinaryTree; case class Nodes(btree:BinaryTree*) extends BinaryTree; case class sNode(oper:String,node:BinaryTree*) extends BinaryTree; def leafsum(btree:BinaryTree):Int={ var sum=0; btree match{ case Node(a,b) =>sum=sum+leafsum(a)+leafsum(b); case Leaf(a) => sum=sum+a; case Nodes(btr@_*) => sum=sum+btr.map(leafsum).sum; } sum }
14.7 扩展前一个练习中的树,使得每个节点可以有任意多的后代,并重新实现leafSum函数。第五题中的树应该能够通过下述代码表示:
sealed abstract class BinaryTree; case class Leaf(value:Int) extends BinaryTree; case class Node(left:BinaryTree,right:BinaryTree) extends BinaryTree; case class Nodes(btree:BinaryTree*) extends BinaryTree; case class sNode(oper:String,node:BinaryTree*) extends BinaryTree; def leafsum(btree:BinaryTree):Int={ var sum=0; btree match{ case Node(a,b) =>sum=sum+leafsum(a)+leafsum(b); case Leaf(a) => sum=sum+a; case Nodes(btr@_*) => sum=sum+btr.map(leafsum).sum; } sum }
14.8 扩展前一个练习中的树,使得每个非叶子节点除了后代之外,能够存放一个操作符。然后编写一个eval函数来计算它的值。举例来说:
+
/ | \
* 2 -
/ \ |
3 8 5
上面这棵树的值为(3 * 8) + 2 + (-5) = 21
sealed abstract class BinaryTree; case class Leaf(value:Int) extends BinaryTree; case class Node(left:BinaryTree,right:BinaryTree) extends BinaryTree; case class Nodes(btree:BinaryTree*) extends BinaryTree; case class sNode(oper:String,node:BinaryTree*) extends BinaryTree; def leafsum(btree:BinaryTree):Int={ var sum=0; btree match{ case Node(a,b) =>sum=sum+leafsum(a)+leafsum(b); case Leaf(a) => sum=sum+a; case Nodes(btr@_*) => sum=sum+btr.map(leafsum).sum; } sum }
def eval(btree:BinaryTree):Int={
btree match{
case sNode(oper,btr@_*) => if(oper=="+") btr.map(eval).sum else if(oper=="*") btr.map(eval).reduceLeft(_*_) else if(oper=="-") btr.map(eval).foldLeft(0)(_-_) else btr.map(eval).reduceLeft(_/_)
case Leaf(v)=>v
}
}
14.9 编写一个函数,计算List[Option[Int]]中所有非None值之和。不得使用match语句。
def evalList(list:List[Option[Int]]):Int={ list.map(_.getOrElse(0)).sum; }
14.10 编写一个函数,将两个类型为Double=>Option[Double]的函数组合在一起,产生另一个同样类型的函数。如果其中一个函数返回None,则组合函数也应返回None。例如:
def f(x:Double) = if(x>=0) Some(sqrt(x)) else None; def g(x:Double) = if(x!=1) Some(1/(x-1)) else None; def compose(x:Double=>Option[Double],y:Double=>Option[Double]):(Double=>Option[Double])={ (f:Double) => if(x(f)==None || y(f)==None) None else if(x(f).get> y(f).get) x(f) else y(f) }
相关文章推荐
- 【学习笔记】CSS概述
- 1052. 卖个萌 (20)
- eclipse加速之禁用JS、jsp等文件的语法验证,eclipsejs
- C++基础::构造函数
- STM32 USB学习笔记9
- Android事件分发机制源码剖析(2)—顶层View对点击事件的分发过程
- HDU2006~2010——题目合集
- [安卓笔记]android客户端向tomcat服务器发送请求中文乱码问题解决
- 多个流,简短的读和写
- 线索化二叉树的非递归遍历(用前驱结点和后继访问)
- 百度地图无法实现重复定位的问题
- Prim算法求MST(最小生成树)
- hadoop面试题
- Spinner三级联动里的next(),nextText(),getText()的一点心得和理解
- [置顶] oracle存储过程
- 关于jsp中重定向的问题
- 看MySql如何实现批量操作
- Tortoise SVN 使用笔记
- hdu 1255(线段树求重叠面积)
- 删除链表中等于给定值val的所有节点。