Recursion 拆分列表的Lisp递归

Recursion 拆分列表的Lisp递归,recursion,split,lisp,common-lisp,Recursion,Split,Lisp,Common Lisp,这是我的密码。它工作得很好: (defun split-list (L) (if (endp L) '(nil nil) (let ((x (split-list (cdr L)))) (list (cons (car L) (cadr x))(car X)) ))) 但是我需要一个关于递归部分的解释 当我们调用函数(拆分列表(cdrl))时,我确信它从123456到23456(车辆L)为1 而且(cadr X)是3,但是5

这是我的密码。它工作得很好:

(defun split-list (L) 
    (if (endp L)
    '(nil nil)  
     (let ((x (split-list (cdr L)))) 
         (list (cons (car L) (cadr x))(car X))
         )))
但是我需要一个关于递归部分的解释

当我们调用函数
(拆分列表(cdrl))
时,我确信它从123456到23456<代码>(车辆L)为1 而且
(cadr X)
是3,但是5是怎么来的呢

函数什么时候做的
(拆分列表(cdr L))
难道
x
不是变成了3456并且
(cadr x)
应该是4吗?这是错误的,另一半也是一样的<代码>(车x)现在应该是3,这是错误的


有人能解释一下吗?

我将重写一个递归的
拆分列表,如下所示:

(split-list '(1 2 3 4 5 6))
((1 3 5) (2 4 6))
上面使用了多个值。函数将分割结果作为两个值返回。我们还将
car
替换为
first
,将
cdr
替换为
rest
。它们只是更好的名称,但具有相同的功能<代码>多值绑定
将递归
拆分列表
调用的两个值绑定到变量
split1
split2
。函数
values
将其两个参数作为两个值返回

在下面的示例中,您可以看到函数确实返回两个值:

(defun split-list (list) 
  (if (endp list)
      (values nil nil)
    (multiple-value-bind (split1 split2)
        (split-list (rest list))
      (values (cons (first list) split2)
              split1))))
您可以跟踪其执行情况:

CL-USER 20 > (split-list '(a b c d e f))
(A C E)
(B D F)
CL-USER 21>(跟踪分割列表)
(拆分列表)
CL-USER 22>(拆分列表(a b c d e f))
0拆分列表>((A B C D E F))
1拆分列表>((B C D E F))
2拆分列表>((C D E F))
3拆分列表>((D E F))
4拆分列表>((E-F))
5拆分列表>((F))
6拆分列表>(无)
6拆分列表<(无-无)
5拆分列表<((F)无)
4份分拆名单<((E)(F))
3份分拆名单<((D F)(E))
2份分拆名单<((C E)(D F))
1份分拆名单<((B D F)(C E))
0分割名单<((A C E)(B D F))
(A、C、E)
(B D F)

谢谢您,先生!我总是在递归的下半部分遇到麻烦。前半部分是去除元素很容易,但下半部分是。这有点令人困惑。不过解释得很好。
CL-USER 21 > (trace split-list)
(SPLIT-LIST)

CL-USER 22 > (split-list '(a b c d e f))
0 SPLIT-LIST > ((A B C D E F))
  1 SPLIT-LIST > ((B C D E F))
    2 SPLIT-LIST > ((C D E F))
      3 SPLIT-LIST > ((D E F))
        4 SPLIT-LIST > ((E F))
          5 SPLIT-LIST > ((F))
            6 SPLIT-LIST > (NIL)
            6 SPLIT-LIST < (NIL NIL)
          5 SPLIT-LIST < ((F) NIL)
        4 SPLIT-LIST < ((E) (F))
      3 SPLIT-LIST < ((D F) (E))
    2 SPLIT-LIST < ((C E) (D F))
  1 SPLIT-LIST < ((B D F) (C E))
0 SPLIT-LIST < ((A C E) (B D F))
(A C E)
(B D F)