赞
踩
版权属于: Postbird - There I am , in the world more exciting!
原文地址: http://www.ptbird.cn/kuaixue-scala-answer-chapter-12.html
转载时必须以链接形式注明原始出处及本声明。
最近看了看《快学scala》,比较好的点在于这本书每一章后面都有一些练习,可以自己去做一下,对于掌握知识来讲还是不错的(像是以前上学后面的习题一样)。
我不知道哪里有答案,也没有认真找过,就自己做了做。
iteye上有一个人写了前几章的答案,可以参考一下,链接为:http://ivaneye.iteye.com/blog/1843331,遗憾的是这个人只写到第九章,我上面的链接也是第九章,后面就没有了。
其实前面的练习我都没有特别认真的做,简单写了写,也参照了一下上面的博客(非常感谢),12章是将简单的高阶函数,对于scala这样讲函数式与面向对象很好的结合的语言,高阶函数是必须掌握的内容,所以我也就花心思做了做练习,并且将10个题的答案写了下来。
只能说,我根据题目都按照他的思想实现了内容,至于答案是不是最优的,这应该是不可能的。
仅供参照。
如果有不同,欢迎指点。
题目简单提一下,可以参照书籍。
这个没什么,就是简单地函数参数的利用而已。
-
- //第一题 LX12_1
-
- def values(func:(Int)=>Int,low:Int,high:Int){
- for( i<- low to high){
- println("("+i+","+func(i)+")")
- }
- }
- //调用函数
- def func(x:Int):Int=x*x
- values(func,-5,5)
这个只要每次返回一个大的值就可以,我用了 if比较大小 懒。。。。
-
- //第二题 LX12_2
- def getMaxByReduceLeft(arr:Array[Int]): Int ={
- arr.reduceLeft((a,b)=>{if(a > b) a;else b})
- }
- //调用函数
- val arr=Array(1,2,3,4,5,6,7,2,3,5)
- println(getMaxByReduceLeft(arr))
我觉得我这个写的有点问题,我默认的类型是Long的,但是练习4说要考虑n<1的情况
因此我就无视了
第三和第四题都是有点问题的
-
- //第三题 LX12_3
- //只考虑 n>1 且 n为Int的情况的解决
- def getFactorialByReduceLeft(num:Long):Long={
- (1:Long).to(num).reduceLeft(_*_)
- }
- //调用函数
- println(getFactorialByReduceLeft(10:Long))
这个提示和第二题唯一的不同就是比较的函数的大小而已,不过我用了一个ans一直记录函数最大值,这样子最后才能返回需要的也就是函数的最大值
-
- //第五题 LX12_5
- def LX12_5(func:(Int)=>Int,inputs:Seq[Int]):Int={
- var ans:Int=0
- inputs.reduceLeft((a,b)=>{
- // println(func(a)+" "+func(b))
- if(func(a) > func(b)){ans=func(a); a}
- else {ans=func(b); b}
- })
- ans
- }
- //测试函数
- def func2(x:Int)=10 *x-x*x
- println(LX12_5(func2,1 to 10))
第五题刚好反过来,需要求最大值时候的输入值,只要让ans记录输入值就行了
-
- //第六题 LX12_6
- //一个意思 没什么的
- def LX12_6(func:(Int)=>Int,input:Seq[Int]):Int ={
- input.reduceLeft((a,b)=>{
- // println(func(a)+" "+func(b))
- if(func(a) > func(b))a
- else b
- })
- }
- //测试函数
- def func3(x:Int)=10*x
- println(LX12_6(func3,1 to 3))
这个题很有意思,首先,通过 zip操作得到的实际上是一个元祖为基础的vector,而进行map的时候不能简单地map(_+_),因为他不是两个int,而是一个tuple2
创建的函数要求能够在map中去处理,看代码。。。
-
- //第七题 LX12_7
- val pairs=(1 to 10) zip (11 to 20)
- //我们都知道map可以每次去处理一个值,但是他不接受tuple
- //所以ajustToPair刚好解决这个问题,能够接受tuple2,并返回另一个函数
- def ajustToPair(func:(Int,Int)=>Int)=(pair:Tuple2[Int,Int])=>{func(pair._1,pair._2)}
- //测试函数
- println(pairs.map(i=>ajustToPair(_ + _)(i)))
这个看看书上的例子很容易就写出来了
-
- //第八题LX12_8
- val tmpStr=Array("hello","scala","postbird")
- val tmpLen=Array(5,5,8)
- // val tmpLen=Array(5,5,7)
- println(tmpStr.corresponds(tmpLen)(_.length==_))
题目说上一题应该是第七题,也就是使用 zip集合map来实现
当然还是要借助我们的ajustToPair函数的
最后我用了res来记录,使用foreach结合 && 操作记录最后是false和true
我写的比较麻烦,但是也实现了。不知到有没有别的方式
-
- //第九题LX12_9
- //不知道前一个联系指的是 7 还是8 应该是 7 因为7用了zip
- //然后用了比较麻烦的实现
- val tmpStr_2=Array("hello","scala","postbird")
- val tmpLen_2=Array(5,5,8)
- // val tmpLen_2=Array(5,5,7)
- val pairs_2=tmpStr_2 zip tmpLen_2
- def ajustToPair_2(func:(String,Int)=>Boolean)=(pair:Tuple2[String,Int])=>{func(pair._1,pair._2)}
- var res:Boolean=true
- pairs_2.map(i=>ajustToPair_2(_.length == _)(i)).foreach(b=>res=res&&b)
- println(res)
一定是需要换名调度,另外需要科里化,不然太麻烦
但实际上 换名调度我只是了解个皮毛
-
- //第十题 LX12_10
- //换名调用和科里化是需要的 可以最简洁的表示
- //省略了() 冒号和 => 的空格是一定要有的
- def unless(condition: =>Boolean)(block: =>Unit){
- if(condition){
- block
- unless(condition)(block)
- }
- }
- //测试函数
- //意思是:除非 到了2,否则就一直输出
- var tmpNum=10
- unless(tmpNum!=2){
- tmpNum-=1
- println(tmpNum)
- }
我在码云存了一个代码片段
git@osc:https://git.oschina.net/postbird/codes/uomv9j0d13lfs2e5hxyar77
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。