它关于LISP程序,常见的lisp

时间:2018-01-30 04:15:27

标签: lisp

可以帮助我们,这是我们讲师给我们的一个教程问题&无论我们尝试了多少,我们似乎都无法破解它。请帮忙

; perform some type/error checking,
;    then call function h to ....

(defun f (L N)
   (cond
       ( (not (listp L) ) nil)
       ( (not (integerp N) ) nil)
       ( (< N 1) nil)
       ( (< (length L) N) nil)
       (t (h L N '() ) )
   )
)

(defun h (L N Acc)
   (cond
       ( (eq N 1) (append Acc (cdr L) ) )
       (t (h (cdr L) (- N 1) (append Acc (list (car L) ) ) ) )
   )
)
  1. 对于函数调用(f '(1 2 3) 1),显示对函数h进行的调用序列(如果有),并显示函数f返回的最终值。

  2. 对于函数调用(f '(1 2 3 4) 3),显示对函数h进行的调用序列(如果有),并显示函数f返回的最终值。

  3. 如果我们发现函数f似乎执行了一些基本的类型/错误检查,然后调用函数h来执行“真正的”工作,那么h实际完成了什么

1 个答案:

答案 0 :(得分:0)

一般性评论

  • 根据规范,你不能认为EQ能够可靠地使用数字。由于N是一个数字,因此您应该使用=代替。
  • H中的COND只有两种可能的结果;可以使用IF重写。
  • 不要在括号之间添加空格,不要在括号中单独使用括号。请遵循Lisp表单的常规格式(例如参见http://lisp-lang.org/style-guide)。
  • H中过度使用APPEND会使代码更加复杂。

功能F

(defun f (L N)
   (cond
       ( (not (listp L) ) nil)
       ( (not (integerp N) ) nil)
       ( (< N 1) nil)
       ( (< (length L) N) nil)
       (t (h L N '() ) )
   )
)

仅当代码到达由T保护的子句时,函数F才会调用H,这仅在所有先前的测试失败时才会发生。 让我们反转所有测试以简化一点,并使用WHEN。 等效形式是:

(defun f (list number)
  (when (and (listp list)
             (integerp number)
             (<= 1 number (length list)))
    (h list number)))

h的第三个参数被省略,因为我们不需要它。

功能H

(defun h (L N Acc)
   (cond
       ( (eq N 1) (append Acc (cdr L) ) )
       (t (h (cdr L) (- N 1) (append Acc (list (car L) ) ) ) )
   )
)

代码在递归的每一步都使用APPEND。可能已添加累加器以使函数尾递归,或者可能只是为了混淆意图。您可以在没有辅助列表的情况下重写H以更好地理解它的作用:

(defun h (list number)
  (if (= number 1)
      (cdr list)
      (cons (car list)
            (h (cdr list) (- number 1)))))

还有一些测试:

(f '(a b c d e f) 3)
=> (A B D E F)

(f '(a b c d e f) 2)
=> (A C D E F)