IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    ANSI Common Lisp Chapter 2 习题答案

    一根稻草发表于 2014-02-18 00:00:00
    love 0

     

    2.给出3种不同表示(abc)的cons表达式。

    (cons ‘abc nil) (cons ‘abc ())

    3.使用car与cdr,定义一个函数,它返回一个列表的第四个元素。

    (defun fourth-of-list (x)
     (car (cdr (cdr (cdr x)))))

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

    (defun my-max (x y)
        (if (> x y)
            x
            y))

    5.这些函数干了什么?

    1)函数a.

    (defun enigma (x)
     (and (not (null x))
      (or (null (car x))
       (enigma (cdr x)))))

    函数功能:判断列表x是否含有nil

    2)函数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))))))

    它对应的python代码大致如下:

    def mystery(x, y):
     if not y:
      return null
     else:
      if y[0]==x:
       return 0
      else:
       z=mystery(x, y[1:])
       return z and (z+1)

    函数功能:返回x在列表y中第一次出现的位置,如果没有,返回nil

    6.下列表达式中,x应该是什么,会得到相同的结果.

    (a) > (car (x (cdr ‘(a (b c) d)))) B (b) > (x 13 (/ 1 0)) 13 (c) > (x #’list 1 nil) (1)

    答案是 car or apply

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

    迭代版本

    (defun has-list (x)
        (do ((a x (cdr a)))
            ((or (null a)(listp (car a))) (if (null a) 0 1))))

    递归版本

    (defun has-list (x)
        (if (null x)
            0
            (if (listp (car x))
                1
                (has-list (cdr x)))))

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

    a.接受一个正整数,并打印出这么数目的点

    迭代版本

    (defun print-dot (n)
        (do ((i 1 (+ i 1)))
            ((> i n) 'done)
                (format t ".")))

    递归的

    (defun print-dot (n)
        (if (> n 0)  (format t "."))
        (if (> n 0) (print-dot (- n 1))))

    b.接受一个列表,并返回a在列表中出现的次数

    迭代版本

    (defun find-a-list (x)
        (let ((count 0))
            (do ((p x (cdr p)))
                ((null p) (format t "a times:~A" count))
              (if (eql (car p) 'a) (setf count (+ count 1))))))

    递归的

    (defun find-a-list (x)
        (if (null x)
            0
            (if (eql (car x) 'a)
                (+ 1 (find-list (cdr x)))
                (find-list (cdr x)))))

    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后没有保存,没有修改列表lst 正确版本:

    (defun summit (lst)
          (setf lst (remove nil lst))
          (apply #'+ lst))

    函数(b)错误原因:没有递归结束条件,应该加上判断lst为空的语句 正确版本:

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


沪ICP备19023445号-2号
友情链接