基本LISP递归,枚举大于3的值

toa*_*ast 4 lisp recursion clisp

我需要一个递归的LISP函数,它枚举任何数字列表> 3的元素数量.我不允许使用let,loops或whiles,只能使用基本的CAR,CDR,SETQ,COND,CONS,APPEND,PROGN ,列表......

这是我对该功能的尝试:

(defun foo (lst) 
  (COND ((null lst) lst) 
    (T (IF (> (CAR lst) 3) 
      (1+ (foo (CDR lst)))
      (foo (CDR lst)) ) ) ) )
Run Code Online (Sandbox Code Playgroud)

函数调用:

(foo '(0 1 2 3 4 5 6))
Run Code Online (Sandbox Code Playgroud)

sep*_*p2k 5

您的代码非常接近正确,只是基本情况中的一个小错误:

对于空列表,您将返回空列表.因此,如果您有列表(6),则添加6个foo空列表,即空列表.这不起作用,因为您无法在列表中添加数字.

您可以通过foo返回0而不是lst何时lst为空来轻松修复它.

作为一种风格注释:混合condif这样,似乎有点多余.我会像这样写,只使用cond:

(defun foo (lst) 
  (cond
    ((null lst)
      0)
    ((> (car lst) 3) 
      (1+ (foo (cdr lst))))
    (T
      (foo (cdr lst)))))
Run Code Online (Sandbox Code Playgroud)

  • 常见lisp的最佳在线资源是(可能)"HyperSpec"(http://www.lispworks.com/documentation/HyperSpec/Front/),并且接近最全面的CL描述. (2认同)

Gar*_*ees 5

一些风格点:

  • 没有必要将一些Lisp内置函数放在大写中.它不再是1958年了!
  • 但是,如果你打算把内置插件大写的,为什么不DEFUNNULL
  • 你有一个if在你的最后一个分支内cond.这是多余的.既然cond是测试条件的目的,为什么不用呢?
  • 没有必要像这样填补你的结束括号.这些天没有人计算括号,我们有括号匹配的编辑器.
  • Lisp具有单独的函数和值命名空间,因此您不必调用您的参数lst来避免与内置函数冲突list.

如果你是真的编程,当然你会使用count-if:

(count-if #'(lambda (x) (> x 3)) '(0 1 2 3 4 5 6))
    ==> 3
Run Code Online (Sandbox Code Playgroud)