勉強のためにListのAPIはなるべく使わない方向で。
- //P12 (**) Decode a run-length encoded list.
- //Given a run-length code list generated as specified in problem P10, construct its uncompressed version.
- //Example:
- //scala> decode(List((4, 'a), (1, 'b), (2, 'c), (2, 'a), (1, 'd), (4, 'e)))
- //res0: List[Symbol] = List('a, 'a, 'a, 'a, 'b, 'c, 'c, 'a, 'a, 'd, 'e, 'e, 'e, 'e)
- def decode[T](xs: List[(Int, T)]) = {
- // not tail recursion
- def ntimes_nottail(n: Int, x: T): List[T] = {
- if (n < 0) throw new IllegalArgumentException
- else if (n == 0) Nil
- else x :: ntimes_nottail(n - 1, x)
- }
- // tail recursion
- def ntimes_tail(ntimes: Int, x: T) = {
- def ntimes_rec(n: Int, result: List[T]): List[T] = {
- if (n == 0) result else ntimes_rec(n - 1, x :: result)
- }
- if (ntimes < 0) throw new IllegalArgumentException else ntimes_rec(ntimes, Nil)
- }
- // tail recursion
- def recursive(ys: List[(Int, T)], result: List[T]): List[T] = ys match {
- case Nil => result
- case (times, x) :: tail => recursive(tail, result ::: ntimes_tail(times, x))
- // case (times, x) :: tail => recursive(tail, result ::: ntimes_nottail(times, x))
- }
- recursive(xs, Nil)
- }
- val l = List((5, 'a), (1, 'b), (2, 'c), (2, 'a), (1, 'd), (4, 'e))
- println(decode(l))
末尾再帰版(ntimes_tail)だと100万回のループでもStackOverFlowにならなかったが、
非末尾再帰版だと10万回でStackOverFlowした。
解答例
そ、そんな!!
No comments:
Post a Comment