【问题标题】:Common Lisp - Function that builds, from a list of numbers, the list of more, smaller or equal to a given numberCommon Lisp - 从数字列表构建更多、小于或等于给定数字的列表的函数
【发布时间】:2018-08-15 17:18:56
【问题描述】:

我在使用此功能时遇到问题, 我想要一个功能 返回给定数字的下级数字列表。

到目前为止我做了什么,

(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)

我错过了什么?

【问题讨论】:

  • 请正确缩进您的代码。必要时使用 Emacs。
  • 代码编译时出现警告:未定义变量cons,应该是cond的默认情况。
  • 问题摘要、问题文本和尝试的实现,指定三个不同的问题。

标签: function lisp common-lisp


【解决方案1】:

首先,您发布的功能与您声称的方式不同。 第一次调用返回(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)

【讨论】:

    【解决方案2】:

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

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

    以上根据#'&lt;删除所有“等于”10的元素,因此所有元素u使得(&lt; 10 u)成立。换句话说,所有元素都严格高于 10:

    (0 3 5 10 3 2)
    

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

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

    编辑:由于这是现在公认的答案,还要注意这种方法可能难以阅读,使用时要小心(添加评论等)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-22
      • 1970-01-01
      • 1970-01-01
      • 2011-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多