연습문제 2.25, 26, 27, 28. car와 cdr을 쓰는 문제

11 views
Skip to first unread message

xeraph

unread,
Dec 24, 2007, 3:17:55 AM12/24/07
to sicp-sig
연습문제 2.25
다음 리스트에서 7을 끄집어내려면 car와 cdr 연산을 어떻게 엮어 써야 하는지 밝혀라.

(1 3 (5 7) 9)
> (car (cdr (car (cdr (cdr '(1 3 (5 7) 9))))))

((7))
> (car (car '((7))))

(1 (2 (3 (4 (5 (6 (7))))))
> (car (car (cdr (car (cdr (car (cdr (car (cdr (car (cdr (car (cdr
'(1 (2 (3 (4 (5 (6 (7))))))))))))))))))))

이렇게 쓰려니 참 지저분하네 -_-;

연습문제 2.26
x와 y의 정의가 다음과 같다고 하자.

(define x (list 1 2 3))
(define y (list 4 5 6))

다음 식의 값을 구했을 때 실행기에서는 그 값을 어떻게 찍어내는가?
이건 그냥 돌려보기만 하면 된다.

> (append x y)
(1 2 3 4 5 6)
> (cons x y)
((1 2 3) 4 5 6)
> (list x y)
((1 2 3) (4 5 6))

연습문제 2.27
연 습문제 2.18에서 만든 reverse 프로시저를 고쳐서, 리스트를 인자로 받는 deep-reverse 프로시저를 짜보라.
deep-reverse 프로시저는 리스트의 원소 차례를 뒤집을 뿐 아니라, 모든 부분 리스트를 따라 내려가서 그 원소들의 차례
도 다 뒤집는다. 두 프로시저를 만들어 돌려보면, 아래와 같은 결과가 나와야 한다.

> (define x (list (list 1 2) (list 3 4)))
> x
((1 2) (3 4))
> (reverse x)
((3 4) (1 2))
> (deep-reverse x)
((4 3) (2 1))

일단 listp 대신 pair?가 쓰인다는 것을 기억하자.

(define (deep-reverse l)
(define (iter l output)
(cond ((null? l) output) ; exit condition
((not (pair? (car l))) ; atom
(iter (cdr l)
(cons (car l) output)))
(else ; list
(iter (cdr l)
(cons (deep-reverse (car l))
output)))))
(iter l '()))

하루종일 삽질하다 더 시간 끌기 힘들어서 그냥 굴러다니는 소스 보고 해석을 해봤다.
기본적으로 출력 담을 리스트 하나 놓고 계속 쌓아나간다.

1. 입력 리스트를 다 소모했다면 출력 리스트를 반환하고 끝내면 된다.
2. 현재 쌍에서 앞쪽에 있는 녀석이 atom이라면 뒷부분을 계속 처리하면서 출력에 atom을 하나 새로 붙여주면 된다.
(거꾸로 자란다.)
3. 만약 앞쪽에 있는 녀석을 따라갔더니 또 pair라고 한다면 뒷부분을 계속 처리하는데, 출력은 pair랑 출력물이랑 붙
여야 한다.

연습문제 2.28
나무를 받아서 평평한 리스트로 만드는 fringe 프로시저를 정의하라.
이런건 껌이다 (..)

(define (fringe tree)
(cond ((eq? tree '()) '())
((not (pair? tree)) (list tree))
(else (append (fringe (car tree))
(fringe (cdr tree))))))

> (fringe '((1 2) (3 4)))
(1 2 3 4)
> (fringe '((1 2 (3 4 (5 6)) 7 9)))
(1 2 3 4 5 6 7 9)
Reply all
Reply to author
Forward
0 new messages