LISP 编程 - 想知道该代码的作用

0 lisp clisp elisp

(defun interleave (x y)
  (cond ((and (null x)(null y)) nil)
        (t (cons (car x) (cons (car y) (interleave (cdr x) (cdr y)))))
Run Code Online (Sandbox Code Playgroud)

想知道上面的代码做什么?

jsa*_*ami 7

它定义了一个交错两个列表的函数。例如,调用它如下:

(interleave '(a b c) '(d e f))
Run Code Online (Sandbox Code Playgroud)

会给清单(a d b e c f)

编辑

这是解释:

  • (defun interleave (x y) ..声明interleave接受 2 个参数(或列表)的函数
  • (cond ((and (null x)(null y) nil) ...)告诉,如果这两个 xynil,回报nilnil是空列表,该函数null检查列表是否为空。在这里,条件作为interleave函数递归调用的终止。
  • (t ...) 如果不满足上述条件,则指定默认操作
  • (cons ...)通过指定列表的头部(第一个参数)和尾部(第二个参数)构造一个新列表。例如:(cons a '(b c))会给(a b c). 请注意,头部应该是单个元素,尾部应该是元素列表。cons这里的一个有用的属性是:(cons a nil) => (a)
  • (car x)检索列表的头部x。例如:(car '(a b c))会返回a. car这里的一个有用的属性是:(car nil) => nil
  • (cdr x)检索列表的尾部x。例如:(cdr '(a b c))将返回(b c). cdr这里有用的属性是:
    • 一个元素列表的尾部是 nil(cdr (a)) => nil
    • 尾部nilnil(cdr nil) => nil
  • (interleave (cdr x) (cdr y))interleave使用两者的尾部递归调用函数xy作为参数。

因此,对于 call (interleave '(a b c) '(d e f)),递归可以表示如下

(interleave '(a b c) '(d e f))
(cons a (cons d (interleave (b c) (e f)))
(cons a (cons d (cons b (cons e (interleave (c) (f))))))
(cons a (cons d (cons b (cons e (cons c (cons f (interleave nil nil)))))))
(cons a (cons d (cons b (cons e (cons c (cons f nil))))))
(cons a (cons d (cons b (cons e (cons c (f))))))
(cons a (cons d (cons b (cons e (c f)))))
(cons a (cons d (cons b (e c f))))
(cons a (cons d (b e c f)))
(cons a (d b e c f))
(a d b e c f)
Run Code Online (Sandbox Code Playgroud)

对于两个列表的长度不相等的情况,我们有例如:

(interleave '(a b c) '(1 0))
(cons a (cons 1 (interleave (b c) (0))))
(cons a (cons 1 (cons b (cons 0 interleave (c) nil))))
(cons a (cons 1 (cons b (cons 0 (cons c (cons nil (interleave nil nil)))))))
(cons a (cons 1 (cons b (cons 0 (cons c (cons nil nil))))))
(cons a (cons 1 (cons b (cons 0 (cons c (nil))))))
(cons a (cons 1 (cons b (cons 0 (c nil)))))
(cons a (cons 1 (cons b (0 c nil))))
(cons a (cons 1 (b 0 c nil)))
(cons a (1 b 0 c nil))
(a 1 b 0 c nil)
Run Code Online (Sandbox Code Playgroud)