声明
该系列文章来自:http://aperiodic.net/phil/scala/s-99/
大部分内容和原文相同,加入了部分自己的代码。
如有侵权,请及时联系本人。本人将立即删除相关内容。

P21 (*) Insert an element at a given position into a list.

要求

Example:

1
2
scala> insertAt('new, 1, List('a, 'b, 'c, 'd))
res0: List[Symbol] = List('a, 'new, 'b, 'c, 'd)

方案

  • (1) take + newElement+ drop
1
2
3
4
5
def insertAt[T](e: T, index: Int, list: List[T]): List[T] = {
if (index < 0 || list == Nil) throw new IllegalArgumentException
list.take(index) ::: List(e) ::: list.drop(index)
}
  • (2)
1
2
3
def insertAt2[A](e: A, n: Int, ls: List[A]): List[A] = ls.splitAt(n) match {
case (pre, post) => pre ::: e :: post
}

P22 (*) Create a list containing all integers within a given range.

要求

Example:

1
2
scala> range(4, 9)
res0: List[Int] = List(4, 5, 6, 7, 8, 9)

方案

  • (1) 内置Range(废话)
1
2
def range(start: Int, end: Int): List[Int] =
Range(start, end + 1).toList
  • (2) 指令式编程(scala中并不推荐)
1
2
3
4
5
6
7
8
9
def range2(start: Int, end: Int): List[Int] = {
var i = 0
var ret = scala.collection.mutable.ListBuffer[Int]()
while (i <= end - start) {
ret.append(start + i)
i += 1
}
return ret.toList
}

P23 (**) Extract a given number of randomly selected elements from a list.

要求

Example:

1
2
3
scala> randomSelect(3, List('a, 'b, 'c, 'd, 'f, 'g, 'h))
res0: List[Symbol] = List('e, 'd, 'a)
Hint: Use the solution to problem P20

方案

  • (1) java.util.Random + p20.removeAt
1
2
3
4
5
6
7
8
def randomSelect[T](count: Int, list: List[T]): List[T] = {
if (count <= 0) Nil
else {
val r = new java.util.Random()
val (rest, removedElement) = removeAt(r.nextInt(list.length), list)
return removedElement :: randomSelect(count - 1, rest)
}
}
1
2
3
4
5
6
7
8
9
def randomSelect2[T](n: Int, ls: List[T]): List[T] = {
def randomSelectR(n: Int, ls: List[T], r: util.Random): List[T] =
if (n <= 0) Nil
else {
val (rest, e) = removeAt(r.nextInt(ls.length), ls)
e :: randomSelectR(n - 1, rest, r)
}
randomSelectR(n, ls, new util.Random)
}

P24 (*) Lotto: Draw N different random numbers from the set 1..M.

要求

Example:

1
2
scala> lotto(6, 49)
res0: List[Int] = List(23, 1, 17, 33, 21, 37)

方案

  • (1) p23.randomSelect + Range()
1
2
def lotto(count: Int, max: Int): List[Int] =
randomSelect(count, List.range(1, max + 1))

P25 (*) Generate a random permutation of the elements of a list.

要求

Hint: Use the solution of problem P23.

Example:

1
2
scala> randomPermute(List('a, 'b, 'c, 'd, 'e, 'f))
res0: List[Symbol] = List('b, 'a, 'd, 'c, 'e, 'f)

方案

  • (1) P23.randomeSelect(太没效率了)
1
2
3
4
def randomPermute[T](list: List[T]): List[T] = {
import Problem23.randomSelect
randomSelect(list.length, list)
}
  • (2) 在mutable的数组中随机交换元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def randomPermute2[T](list: List[T]): List[T] = {
val arr = scala.collection.mutable.ArrayBuffer[T]()
//第一个for只想把list转换为Array
//无奈List.toArray总是出错,只好用这个了
for (e <- list) {
arr.append(e)
}
//这里才是正题
val r = new java.util.Random()
for (i <- list.length - 1 until 0 by -1) {
val index = r.nextInt(i)
val tmp = arr(index)
arr(index) = arr(i)
arr(i) = tmp
}
arr.toList
}