勉強のために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