리스트는 연결 구조이자 약속이다.
각 car에는 한 항목을, 각 cdr에는 나머지 리스트를 둔다는 약속을 따르면 순서쌍이 수열이 됩니다.
생각해 볼 질문
재귀 프로시저는 리스트의 모양을 어떻게 따라갈까요?
- 리스트를 첫 항목과 남은 수열로 읽기
- 빈 리스트를 기저 사례로 알아보기
- 입력을 변경하지 않고 새 리스트 만들기
- 연결된 수열 접근과 인덱스 수열 접근 비교하기
length는 남은 수열이 있는지 묻습니다. 비어 있지 않은 순서쌍 하나마다 1을 더하고 cdr을 더 작은 문제로 남깁니다. 빈 리스트가 재귀를 끝냅니다.
append도 같은 모양을 따르며 왼쪽 수열을 새로 만듭니다. 마지막 cdr은 오른쪽 수열을 가리키므로 두 입력의 순서를 그대로 유지합니다.
벡터는 인덱스를 사용하는 수열 약속입니다. vector-ref는 위치로 항목을 고르고 vector-set!은 전체 벡터를 다시 만들지 않고 한 위치를 바꿉니다.
(begin
(define (length items)
(if (null? items)
0
(+ 1 (length (cdr items)))))
(define (append left right)
(if (null? left)
right
(cons (car left) (append (cdr left) right))))
(list (length '(a b c d))
(append '(a b) '(c d))))리스펙스 학습용 런타임리스펙스 SICP 프로필 1.0.0
리스펙스 SICP 런타임 불러오는 중
리스펙스 · SICP 코드UTF-8 280 / 1,048,576바이트
예제
결과—
- 출력
- —
- 값
- —
- 진단
- —
보이는 실행 흐름0 / 0 개의 실행 이벤트
첫 프로그램은 (4 (a b c d))를 반환합니다.
cdr이 현재 문제를 어떻게 줄이는지 보세요. append는 왼쪽 입력의 항목마다 새 순서쌍 하나를 만든 뒤 오른쪽 입력에 닿습니다. 벡터 예제에서는 인덱스 2를 바꾼 다음 그 위치를 다시 읽는 과정을 찾으세요. 이 실행 흐름은 한 번의 실행을 보는 제한된 학습 화면이며 리스펙스 바우치나 권한이 아닙니다.
힌트를 보기 전에 프로그램을 바꿔 보세요.
지금까지 만든 결과를 들고 다니는 도우미 프로시저를 사용해 reverse를 정의하세요. (a b c d)로 시험해 보세요.
힌트 하나 보기
남은 입력의 car를 누산기의 맨 앞에 옮기세요.