Pulpcode

捕获,搅碎,拼接,吞咽

0%

ANSI Common Lisp 第二章习题

问题: 1.描述下列表达式求值之后的结果:

1
2
3
4
5
6
7
8
;; (a)
(+ (- 5 1) (+ 3 7))
;; (b)
(list 1 (+ 2 3))
;; (c)
(if (listp 1) (+ 1 2) (+ 3 4))
;; (d)
(list (and (listp 3) t) (+ 1 2))

答案:

1
2
3
4
5
6
7
8
;; (a)
14
;; (b)
(1 5)
;; (c)
7
;; (d)
(nil 3)

问题: 2.给出 3 种不同表示 (a b c) 的 cons 表达式

1
2
3
4
5
6
;; (a)
(cons 'a '(b c))
;; (b)
(cons 'a (cons 'b '(c)))
;; (c)
(cons 'a (cons 'b (cons 'c nil)))

答案: 3.使用 car 与 cdr 来定义一个函数,返回一个列表的第四个元素

1
2
(defun four (x)
(car (cdr (cdr (cdr x)))))

问题: 4.定义一个函数,接受两个实参,返回两者当中较大的那个

答案:

1
2
3
4
(defun mymax (x y)
(if (> x y)
x
y))

问题:5.这些函数做了什么?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
;; (a)
(defun enigma (x)
(and (not (null x))
(or (null (car x))
(enigma (cdr x)))))

;;(b)
(defun mystery (x y)
(if (null y)
nil
(if (eql (car y) x)
0
(let ((z (mystery x (cdr y))))
(and z (+ z 1))))))

答案:

(a) 判读一个`list`是否包含`nil`元素。
(b) 返回一个列表第一次包含该元素的位置

问题:6.下列表达式, x 该是什么,才会得到相同的结果?

1
2
3
4
5
6
7
8
9
;; (a)
(car (x (cdr '(a (b c) d))))
;; B
;; (b)
(x 13 (/ 1 0))
;; 13
;; (c)
(x #'list 1 nil)
;; (1)

答案:

1
2
3
4
5
6
;; (a)
(car (car (cdr '(a (b c) d))))
;; (b)
(or 13 (/ 1 0))
;; (c)
(apply #'list 1 nil)

问题:7.只使用本章所介绍的操作符,定义一个函数,它接受一个列表作为实参,如果有一个元素是列表时,就返回真。

答案:

1
2
3
4
5
(defun onlyone(x)
(and
(not(equal x '()))
(equal '() (cdr x))
t))

问题:8.给出函数的迭代与递归版本:

(a) 接受一个正整数,并打印出数字数量的点。
(b) 接受一个列表,并返回 a 在列表里所出现的次数。

答案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
;; 迭代版本
(defun show-point (n)
(do ((i 0 (+ i 1)))
((= i n) 'done)
(insert ".")))
;; 递归版本
(defun show-point (n)
(if (= n 0)
'done
(progn (show-point (- n 1))
(insert "."))))

;; 迭代版本
(defun show-count (li m)
(let ((len 0))
(dolist (obj li)
(if (equal m obj)
(setf len (+ len 1)))
)len))

;; 递归版本
(defun show-count (li m)
(if (equal li '())
0
(+ (if (equal (car li) m)
1 0)
(show-count (cdr li) m))))

问题: 9.一位朋友想写一个函数,返回列表里所有非 nil 元素的和。他写了此函数的两个版本,但两个都不能工作。请解释每一个的错误在哪里,并给出正确的版本。

1
2
3
4
5
6
7
8
9
10
11
;; (a)
(defun summit (lst)
(remove nil lst)
(apply #'+ lst))

;; (b)
(defun summit (lst)
(let ((x (car lst)))
(if (null x)
(summit (cdr lst))
(+ x (summit (cdr lst))))))

答案:

1
2
3
4
5
6
7
8
9
10
11
(defun summit (lst)
(setf lst (remove nil lst))
(apply #'+ lst))

(defun summit (lst)
(if (equal '() lst)
0
(let ((x (car lst)))
(if (null x)
(summit (cdr lst))
(+ x (summit (cdr lst)))))))