Common Lisp-从数字列表构建更多,较小或等于给定数字的列表的功能

时间:2018-08-15 17:18:57

标签: function lisp common-lisp

我在使用此功能时遇到麻烦, 我想要一个功能 返回给定数字的劣等数字列表。

我到目前为止所做的,

(defun inf (n l)
(cond
((not l) 0)
((>= n (car l))(cons n (inf n(cdr l))))
(cons (car l) (inf n (cdr l))) ))

但是它保持回报

(inf 12 '(12 5 3))
(12 12 10)

代替:

(inf 12 '(12 5 3 53 45))
(12 5 3)

我想念什么?

2 个答案:

答案 0 :(得分:4)

首先,您发布的功能与您声明的方式不符。 第一次调用返回(12 12 12 . 0)(因为在第一个cond子句中返回0而不是nil) 并且第二次调用引发异常

  

COND:变量CONS没有值

因为您的cond语法错误。

第二,问题摘要,问题文本和尝试的内容 实施,请指定 三个 不同的问题。

这是您代码的修复程序(我已替换为 car and cdrfirstrest出于教学原因):

(defun inf (n l)
  (cond
    ((not l) ())                ; return empty list
    ((>= n (first l))
     (cons n (inf n (rest l))))
    (t
     (cons (first l) (inf n (rest l))))))

实际上,如果这是您想要的,则可以在更多 惯用方式:

(defun inf-1 (n l)
  (and l (cons (max n (first l)) (inf-1 n (rest l)))))

甚至

(defun inf-2 (n l)
  (mapcar (lambda (x) (max n x)) l))

如果您实际上想要的数字列表少于给定的数字,则您 可以使用remove

(remove 12 '(12 5 3 100) :test #'<=)
==> (5 3)

答案 1 :(得分:3)

使用Common Lisp的现有功能来解决同一问题的一种不太明显的方法是将比较运算符传递给REMOVE

(remove 10 '(0 3 5 11 22 10 22 3 2) :test #'<)

以上根据#'<删除了所有等于10的元素,因此所有元素u使得(< 10 u)成立。换句话说,所有元素均严格高于10:

(0 3 5 10 3 2)

事实证明,上面链接的部分中有一个示例:

(remove 3 '(1 2 4 1 3 4 5) :test #'>) =>  (4 3 4 5)

编辑:由于这是目前公认的答案,因此请注意,这种方法可能很难阅读,使用时要小心(添加评论等)。