+++
title = “ANSI Common Lisp 第二章课后题”
date = 2021-07-20
draft = false
+++
-
描述下列表达式求值之后的结果:
(+ (- 5 1) (+ 3 7)) (list 1 (+ 2 3)) (if (listp 1) (+ 1 2) (+ 3 4)) (list (and (listp 3) t) (+ 1 2))
- 运行结果如下
14 (1 5) 7 (nil 3)
-
给出 3 种不同表示 (a b c) 的 cons 表达式。
(cons 'a '(b c)) (cons 'a (cons 'b (cons 'c nil))) (cons 'a (cons 'b '(c)))
-
使用
car
与cdr
来定义一个函数,返回一个列表的第四个元素。(defun get-fourth (x) (car (cdr (cdr (cdr x)))))
-
定义一个函数,接受两个实参,返回两者当中较大的那个。
(defun my-greater (x y) (if (> x y) x y))
-
这些函数做了什么?
(defun enigma (x) (and (not (null x)) (or (null (car x)) (enigma (cdr x))))) (defun mystery (x y) (if (null y) nil (if (eql (car y) x) 0 (let ((z (mystery x (cdr y)))) (and z (+ z 1))))))
-
第一个函数判断传入的列表中是否包含
nil
。and部分判断是否为空表,如果是返回nil
否则进入or中;or判断列表的第一个元素是否为nil,是则返回t
否则对剩余部分应用该函数。 -
第二个函数返回符号x在列表y中第一次出现的index
-
-
下列表达式,
x
该是什么,才会得到相同的结果?(a) > (car (x (cdr '(a (b c) d)))) B (b) > (x 13 (/ 1 0)) 13 (c) > (x #'list 1 nil) (1)
-
car
-
and
-
apply,不能填funcall
-
-
只使用本章所介绍的操作符,定义一个函数,它接受一个列表作为实参,如果有一个元素是列表时,就返回真。
(defun solution-7 (x) (if (null x) nil (if (listp (car x)) t (solution-7 (cdr x)))))
-
给出函数的迭代与递归版本:
- 接受一个正整数,并打印出数字数量的点。(就是打印指定数量的点)
- 接受一个列表,并返回 a 在列表里所出现的次数。
;; 递归版本 (defun solution-8a (x) (or (= 0 x) (progn (format t "~A" ".") (solution-8a (- x 1)) ))) ;; 迭代版本 (defun solution-8b (x) (do ((i x (- i 1))) ((= i 0) 'done) (format t "~A" ".")))
;; 迭代版本 (defun solution-8c (x) (let ((count 0)) (dolist (i x) (if (eq i 'a) (setf count (+ count 1)))) count)) ;; 递归版本 (defun solution-8d (x) (let ((count 0)) (and (not (null x)) (if (eq (car x) 'a) (setf count (+ (solution-8d (cdr x)) 1)) (setf count (solution-8d (cdr x))))) count))
-
一位朋友想写一个函数,返回列表里所有非 nil 元素的和。他写了此函数的两个版本,但两个都不能工作。请解释每一个的错误在哪里,并给出正确的版本。
(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))))))
-
函数(a)的错误在于
remove
不改变原始的表。修改版本如下(defun summit (lst) (setf lst (remove nil lst)) (apply #'+ lst))
-
函数(b)的错误在于没有终止条件导致无限循环
(defun summit (lst) (if (null lst) 0 (let ((x (car lst))) (if (null x) (summit (cdr lst)) (+ x (summit (cdr lst)))))))
-