2013-11-23 9 views
1

이는 커먼 리스프 코드 :상호 재귀 공통의 리스프

(defun take (L) 
    (if (null L) nil 
    (cons (car L) (skip (cdr L))))) 

(defun skip (L) 
    (if (null L) nil 
    (cons (car L) (take (cdr L))))) 

생각이 여기 입력 목록에있는 모든 홀수 순서 요소를 줄 것이다 "걸릴"모든을 줄 것이다 "건너 뛰기"이다 입력 목록의 시퀀스 요소를 짝수로 만듭니다. 그러나 두 경우 모두 전체 목록이 반환됩니다.

이 코드의 오류는 무엇입니까? SML의 비슷한 코드가 원하는 출력을 제공하기 때문에 CL이 목록을 처리하는 방법과 관련이 있습니다. 즉 신비 없도록

fun take(lst) = 
    if lst = nil then nil 
    else hd(lst)::skip(tl(lst)) 
and 
    skip(lst) = 
    if lst = nil then nil 
    else hd(lst)::take(tl(lst)); 
+0

'take'는 홀수 색인 요소를 반환하지 않지만 짝수 요소는 반환합니다. '(car L) == (nth 0 L)'을 포함하면 '0', 'take'는 '0', '2', '4'등의 원소를 반환합니다. –

답변

4

Sylwester가 말한 것에 대해 설명하면 skip은 Lisp 및 SML 모두에서 잘못되었습니다. 그것은

(defun take (L)   ; even-indexed elements of a list L 
    (if (not (null L)) 
    (cons (car L) (skip (cdr L))))) 

(defun skip (L)   ; odd-indexed elements of a list L 
    (if (not (null L)) 
    (take (cdr L)))) 

fun take(lst) = 
    if lst = nil then nil 
    else hd(lst)::skip(tl(lst)) 
and 
    skip(lst) = 
    if lst = nil then nil 
    else take(tl(lst)); 
+1

Btw, 하나의 브랜치 (if ... not ...) ... 대신에 ...를 사용하는 것을 고려하십시오. – PuercoPop

+0

@PuercoPop 고마워,하지만 나는별로 싫어하지만, 매우 혼란 스럽다. 나 : 그것은 다른 방식으로 영어로 사용됩니다. CL에서 "... 않으면 이것을해라"는 동안 "do not는 이것을하지 마라." 게다가, 그건 내 코드가 아니야, 그게 OP 야. 나는 단지 그것을 고쳤다. :) –

3

takeskip는 동일하다. skipcons- 대신 단지 꼬리를 호출해야합니다. 여기에 반환하는 것은 consing입니다.

2

그것은 (다른 많은 프로그래밍 언어와 같은) 커먼 리스프에서 색인이 0으로 시작 지적 가치, 그래서 목록의 짝수 색인 요소가 있어야한다 첫 번째, 세 번째, 다섯 번째, 등등에 인덱스 0, 2, 4 등이 있기 때문에 Common Lisp에서는 빈리스트를 rest으로 가져와 빈리스트를 얻을 수 있습니다. (모든 Lisp에서 이것을 할 수는 없습니다. 예를 들어, Scheme에서는 cdr을 쌍으로 사용하지 마십시오.) 이것은 쉽게 even-elementsodd-elements을 구현할 수 있음을 의미합니다. even-elements은 첫 번째 요소의 목록과 나머지 목록의 홀수 요소를 반환합니다. (odd-elements x)에 대한 호출은 단지 전화는 것을 당신이주의 경우 물론

CL-USER> (even-elements '(0 1 2 3 4 5)) 
(0 2 4) 
CL-USER> (odd-elements '(0 1 2 3 4 5)) 
(1 3 5) 

:

(defun even-elements (list) 
    (if (endp list) list 
     (list* (first list) (odd-elements (rest list))))) 

(defun odd-elements (list) 
    (even-elements (rest list))) 

이 예상 된 방식으로 행동 : odd-elements 목록의 나머지의 even-elements을 반환 (even-elements (rest x))의 경우 even-elements을 다음과 같이 구현할 수 있었고 동일한 결과를 얻을 수있었습니다.

(defun even-elements (list) 
    (if (endp list) list 
     (list* (first list) (even-elements (rest (rest list))))))