2013-11-23 145 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))))))