Gauche本勉強メモ(6日目)

6.5 簡単なリスト処理

空でないリストの最後の対を見つけるlast-pairを書いてみる。

こんな感じだろうか?

(define (last-pair2 lis)
  (if (pair? lis)
	  (last-pair2 (cdr lis))
	  lis))

gosh> (last-pair2 '(1 2 3))
()
gosh> (last-pair2 '(1 . 3))
3

だめだ。最後の対じゃなくて最後の要素返してる。
本をもうちょっと読み進めてみる。

リストの最後の対ということはリストのcdrが対ではないということ

なるほど。

じゃあこれでどうだろ?

(define (last-pair2 lis)
  (if (pair? (cdr lis))
	  (last-pair2 (cdr lis))
	  lis))

gosh> (last-pair2 '(1 2 3))
(3)
gosh> (last-pair2 '(1 . 3))
(1 . 3)

よさげ。

次は、リストをコピーするcopy-listを考えてみる。(「ただし、リストを構成する対を複製することとする」という但し書きがあるがよくわからない。一段目の要素しか考えないということ?)
ん?リストをコピーするっていうのは渡されたリストをそのまま返して他の変数へ代入するではだめなの?

(define lis2 lis)

みたいな。あ、これだと参照がコピーされてるだけで、lisを変更するとlis2まで変わっちゃうのかな?

gosh> (define lis '(1 2 3))
lis
gosh> lis
(1 2 3)
gosh> (define lis2 lis)
lis2
gosh> lis2
(1 2 3)
gosh> (define lis '(5 5 5))
lis
gosh> lis
(5 5 5)
gosh> lis2
(1 2 3)

あれ?そんなことないな。

本に載っている定義は

(define (copy-list lis)
  (if (pair? lis)
	  (cons (car lis) (copy-list (cdr lis)))
	  lis))

deep-copy-list(ネストしたリストもすべてコピーする)も考えてみる。

(define (deep-copy-list lis)
  (if (pair? lis)
	  (if (pair? (car lis))
		  (cons (deep-copy-list (car lis))
				(deep-copy-list (cdr lis)))
		  (cons (car lis) (deep-copy-list (cdr lis))))
	  lis))

こう?なんかつかれて頭があまり働いてないな。

ネストしたリストをcopy-listというdeep-copy-listの両方で試してみる。

gosh> (copy-list '((1 2 3) (4 5) 6 7 ((8 9) 10)))
((1 2 3) (4 5) 6 7 ((8 9) 10))

gosh> (deep-copy-list '((1 2 3) (4 5) 6 7 ((8 9) 10)))
((1 2 3) (4 5) 6 7 ((8 9) 10))

あれ?おなじになっちゃった。copy-listのほうでもネストしたリストコピーできてる。
うーん。


今日はここまで。