ANSI Common Lisp 第二章课后题

+++
title = “ANSI Common Lisp 第二章课后题”
date = 2021-07-20
draft = false
+++

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

    (+ (- 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)
    
  2. 给出 3 种不同表示 (a b c) 的 cons 表达式。

    (cons 'a '(b c))
    (cons 'a (cons 'b (cons 'c nil)))
    (cons 'a (cons 'b '(c)))
    
  3. 使用 carcdr 来定义一个函数,返回一个列表的第四个元素。

    (defun get-fourth (x)
      (car (cdr (cdr (cdr x)))))
    
  4. 定义一个函数,接受两个实参,返回两者当中较大的那个。

    (defun my-greater (x y)
      (if (> x y) x y))
    
  5. 这些函数做了什么?

    (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

  6. 下列表达式, 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

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

    (defun solution-7 (x)
      (if (null x)
          nil
          (if (listp (car x))
    	  t
    	  (solution-7 (cdr x)))))
    
  8. 给出函数的迭代与递归版本:

    1. 接受一个正整数,并打印出数字数量的点。(就是打印指定数量的点)
    2. 接受一个列表,并返回 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))
    
    
  9. 一位朋友想写一个函数,返回列表里所有非 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)))))))
      
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值