ANSI Common Lisp 第二章习题解答
本文是个人对第二章:欢迎来到 Lisp——ANSI Common Lisp 中文版 一文中习题的解答。
1. 描述下列表达式求值之后的结果:
(a) (+ (- 5 1) (+ 3 7))
答案:14
(b) (list 1 (+ 2 3))
答案:(1 5)
(c) (if (listp 1) (+ 1 2) (+ 3 4))
答案:7
(d) (list (and (listp 3) t) (+ 1 2))
答案:(NIL 3)
2. 给出 3 种不同表示 (a b c) 的 cons 表达式 。
答案:
1 | (cons 'a '(b c)) |
3. 使用 car 与 cdr 来定义一个函数,返回一个列表的第四个元素。
答案:
1 | (defun get-forth(lst) |
4. 定义一个函数,接受两个实参,返回两者当中较大的那个。
答案:
1 | (defun get-max(x y) |
5. 这些函数做了什么?
(a)
1 | (defun enigma (x) |
答案:判断 x 列表中是否有 nil 元素
(b)
1 | (defun mystery (x y) |
答案:查找 x 在列表 y 中的下标,如果没有则为 nil
6. 下列表达式, x 该是什么,才会得到相同的结果?
(a) > (car (x (cdr ‘(a (b c) d))))
B
答案:car
(b) > (x 13 (/ 1 0))
13
答案:or
(c) > (x #’list 1 nil)
(1)
答案:or '(1)
或 apply
7. 只使用本章所介绍的操作符,定义一个函数,它接受一个列表作为实参,如果有一个元素是列表时,就返回真。
答案:
非递归版本
1 | (defun has-child-list (lst) |
递归版本
1 | (defun has-child-list-re (lst) |
8. 给出函数的迭代与递归版本:
a. 接受一个正整数,并打印出数字数量的点。
答案:
非递归版本
1 | (defun print-dots (n) |
递归版本
1 | (defun print-dots-re (n) |
b. 接受一个列表,并返回 a 在列表里所出现的次数。
答案:
非递归版本:
1 | (defun print-a-times (lst) |
递归版本:
1 | (defun print-a-times-re (lst) |
9. 一位朋友想写一个函数,返回列表里所有非 nil 元素的和。他写了此函数的两个版本,但两个都不能工作。请解释每一个的错误在哪里,并给出正确的版本。
(a)
1 | (defun summit (lst) |
答案:因为 remove 并不会改变 lst 本身。正确的程序:
1 | (defun summit (lst) |
(b)
1 | (defun summit (lst) |
答案:因为递归没有边界退出分支。正确的程序:
1 | (defun summit (lst) |