2013-11-23 177 views
1

這是Common Lisp的代碼:相互遞歸Common Lisp中

(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))))) 

這裏的想法是,「走」將給所有在輸入列表中的奇數序列的元素和「跳過」將會給所有的甚至是輸入列表中的序列元素。但是,在這兩種情況下,整個列表都會返回。

此代碼中的錯誤是什麼?這與CL如何處理列表有關,因爲SML中的類似代碼提供了所需的輸出。

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'不會返回奇怪的索引元素,而是返回偶數個元素。索引從'0'開始,如果它包括'(car L)==(nth 0 L)','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

順便說一句,考慮使用(除非...),而不是一個分支(如果(不......)...) – PuercoPop

+0

@PuercoPop謝謝,但我不喜歡',除非'非常非常非常混亂,我:在英語中它被用於不同的形式,它是「不要這樣做,除非......」,而在CL中它是「除非......,這樣做」。此外,它不是我的*代碼,它是OP的。我只修正了它。 :) –

3

takeskip是相同的,使得沒有謎。 skip應該只是尾呼而不是cons -ing。這是讓這裏迴歸的考慮因素。

2

值得指出的是,索引Common Lisp中(如許多其他編程語言),從0開始,所以一個列表的偶數索引元素第一個,第三個,第五個等等,因爲那些索引爲0,2,4等。值得注意的是,在Common Lisp中,可以將空列表中的rest取回到空列表中。 (但是,在每個Lisp中都不能這樣做,例如,在Scheme中,對於不是一對的東西,調用cdr是錯誤的。)這意味着您可以相當容易地實現even-elementsodd-elementseven-elements只是返回第一個元素的列表,以及列表中其餘元素的奇數元素。 odd-elements返回列表的其餘部分的even-elements

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

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

這些行爲按預期方式:

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) 

當然,如果你注意的是,調用(odd-elements x)僅僅是一個電話(even-elements (rest x)),我們可以執行如下even-elements,並且具有相同的結果:

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