《快学scala》习题解答-第四章-映射与元组

《快学Scala》(英文版:《Scala for the Impatient》),代码已传github:

https://github.com/vernonzheng/scala-for-the-Impatient

书为第一版。scala为2.11.4,jdk1.7.45,操作系统Mac OS X Yosemite 10.10.1。

第四章 映射和元组

4.1
设置一个映射,其中包含你想要的一些装备,以及它们的价格。然后构建另一个映射,采用同一组键,但是价格上打9折

答:

1
2
3
4
def buildEquipMap() :Map[String,Double] = {
val equipMap:Map[String,Double] = Map("eq1"->11.1,"eq2"->12.2,"eq3"->14)
for ((k,v) <- equipMap) yield (k,v*0.9)
}

4.2
编写一段程序,从文件中读取单词。用一个可变映射来清点每个单词出现的频率。读取这些单词的操作可以使用java.util.Scanner

答:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import scala.collection.mutable
import scala.io.Source
def countWord() : Unit = {
val wordMap = new mutable.HashMap[String,Int]
val in = new java.util.Scanner(new java.io.File("exercise02.txt"))
while(in.hasNext){
val word = in.next()
wordMap(word) = wordMap.getOrElse(word,0) + 1
}
println(wordMap.mkString(","))
}
def countWord2() : Unit = {
val source = Source.fromFile("exercise02.txt").mkString
val tokens = source.split("\\s+")
val wordMap = new mutable.HashMap[String,Int]
for(word <- tokens){
wordMap(word) = wordMap.getOrElse(word,0) + 1
}
println(wordMap.mkString(","))
}

4.3
重复前一个练习,这次用不可变的映射

答:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
mport scala.collection.{mutable, immutable}
import scala.io.Source
def countWord() : Unit = {
val source = Source.fromFile("exercise02.txt").mkString
val tokens = source.split("\\s+")
var wordMap = new immutable.HashMap[String,Int]
for(key <- tokens){
wordMap += (key -> (wordMap.getOrElse(key,0) + 1))
}
println(wordMap.mkString(","))
}
/**
* 书中:immutable map += 不断生成新的map,由于都是immutable,共享大部分数据结构,
* 测试下性能
*/
def countWord1(tokens:Array[String]) : Unit = {
val wordMap = new mutable.HashMap[String,Int]
for(word <- tokens){
wordMap(word) = wordMap.getOrElse(word,0) + 1
}
}
def countWord2(tokens:Array[String]) : Unit = {
val wordMap = new mutable.HashMap[String,Int]
for(word <- tokens){
wordMap(word) = wordMap.getOrElse(word,0) + 1
}
}
def performance():Unit={
val source = Source.fromFile("exercise02.txt").mkString
val tokens = source.split("\\s+")
val startTime1 = System.currentTimeMillis()
for(i <- 0 to 10000) {
countWord1(tokens)
}
val endTime1 = System.currentTimeMillis()
val startTime2 = System.currentTimeMillis()
for(i <- 0 to 10000) {
countWord2(tokens)
}
val endTime2 = System.currentTimeMillis()
println("countWord1(mutable map) cost:"+(endTime1-startTime1))
println("countWord2(immutable map) cost:"+(endTime2-startTime2))
/**
* scala> performance
countWord1(mutable map) cost:36
countWord2(immutable map) cost:34
scala> performance
countWord1(mutable map) cost:4
countWord2(immutable map) cost:4
scala> performance
countWord1(mutable map) cost:8
countWord2(immutable map) cost:6
scala> performance
countWord1(mutable map) cost:4
countWord2(immutable map) cost:8
scala> performance
countWord1(mutable map) cost:5
countWord2(immutable map) cost:4
*/
}

4.4
重复前一个练习,这次使用已排序的映射,以便单词可以按顺序打印出来

答:

1
2
3
4
5
6
7
8
9
10
11
12
import scala.collection.immutable.TreeMap
import scala.io.Source
def countWord() : Unit = {
val source = Source.fromFile("exercise02.txt").mkString
val tokens = source.split("\\s+")
var wordMap = new TreeMap[String,Int]
for(key <- tokens){
wordMap += (key -> (wordMap.getOrElse(key,0) + 1))
}
println(wordMap.mkString(","))
}

4.5
重复前一个练习,这次使用java.util.TreeMap并使之适用于Scala API

答:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.util
import scala.collection.mutable.Map
import scala.collection.JavaConversions.mapAsScalaMap
import scala.io.Source
def countWord() : Unit = {
val source = Source.fromFile("exercise02.txt").mkString
val tokens = source.split("\\s+")
var wordMap:Map[String,Int] = new util.TreeMap[String,Int]
for(key <- tokens){
wordMap += (key -> (wordMap.getOrElse(key,0) + 1))
}
println(wordMap.mkString(","))
}

4.6
定义一个链式哈希映射,将”Monday”映射到java.util.Calendar.MONDAY,依次类推加入其他日期。展示元素是以插入的顺序被访问的

答:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import java.util.Calendar
import scala.collection.mutable
def calendarDays():Unit = {
val daysMap = mutable.LinkedHashMap(
"Monday" -> Calendar.MONDAY,
"Tuesday" -> Calendar.TUESDAY,
"Wednesday" -> Calendar.WEDNESDAY,
"Thursday" -> Calendar.THURSDAY,
"Friday" -> Calendar.FRIDAY,
"Saturday" -> Calendar.SATURDAY,
"Sunday" -> Calendar.SUNDAY
)
println(daysMap.mkString(","))
}

4.7
打印出所有Java系统属性的表格

答:

1
2
3
4
5
6
7
import scala.collection.JavaConversions.propertiesAsScalaMap
def printJavaSysProps():Unit = {
val propMap:collection.Map[String,String] = System.getProperties()
val maxKeyLength = propMap.keySet.map(_.length).max
for( (k,v) <- propMap ) printf("%-" + maxKeyLength + "s | %s\n", k, v)
}

4.8
编写一个函数minmax(values:Array[Int]),返回数组中最小值和最大值的对偶

答:

1
2
3
def minmax(values:Array[Int])={
(values.max,values.min)
}

4.9
编写一个函数Iteqgt(values:Array[int],v:Int),返回数组中小于v,等于v和大于v的数量,要求三个值一起返回

答:

1
2
3
def Iteqgt(values:Array[Int],v:Int){
(values.count(_ < v),values.count(_ == v),values.count(_ > v))
}

4.10
当你将两个字符串拉链在一起,比如”Hello”.zip(“World”),会是什么结果?想出一个讲得通的用例

答:

1
2
scala> "Hello".zip("hello").toMap
res40: scala.collection.immutable.Map[Char,Char] = Map(H -> h, e -> e, l -> l, o -> o)

StringOps中的zip定义如下:

abstract def zipB: StringOps[(A, B)]
GenIterable是可遍历对象需要包含的trait,对于String来说,它是可遍历的。但是它的遍历是遍历单个字母。 所以拉链就针对每个字母来进行。


参考:
《快学Scala》:http://book.douban.com/subject/19971952/

(转载本站文章请注明作者和出处 Vernon Zheng(郑雪峰) – vernonzheng.com ,请勿用于任何商业用途)