; 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) ) ) ) )
)
)
对于函数调用(f '(1 2 3) 1)
,显示对函数h
进行的调用序列(如果有),并显示函数f
返回的最终值。
对于函数调用(f '(1 2 3 4) 3)
,显示对函数h
进行的调用序列(如果有),并显示函数f
返回的最终值。
如果我们发现函数f
似乎执行了一些基本的类型/错误检查,然后调用函数h来执行“真正的”工作,那么h
实际完成了什么
答案 0 :(得分:0)
EQ
能够可靠地使用数字。由于N
是一个数字,因此您应该使用=
代替。H
中的COND
只有两种可能的结果;可以使用IF
重写。H
中过度使用APPEND
会使代码更加复杂。(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
的第三个参数被省略,因为我们不需要它。
(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)