怎么写一个函数找出Common lisp中的所有奇数?

时间:2016-03-02 02:35:09

标签: recursion iteration common-lisp

这是我的功能,它从列表中返回所有奇数:

(defun check-all-oddp (n)
   (cond ((null n) nil)
         ((oddp (first n))
           (cons (first n)
                 (check-all-oddp (rest n))))
         (t (check-all-oddp (rest n)))))

我写的使用递归。如何在没有递归的情况下使用do重写它?

2 个答案:

答案 0 :(得分:3)

这样做的一种方法是在do内积累一个列表,只预先添加奇数,然后在结尾处反转列表:

(defun odds-of (numbers)
  (do ((x numbers (cdr x))
       (odds '() (if (oddp (car x)) (cons (car x) odds) odds)))
      ((null x) 
       (nreverse odds))))

我们前置然后反转而不是追加的原因是因为前置是 O(1)而倒车是 O(n),而附加是 O(n)因此重复追加将导致二次时间复杂度。

答案 1 :(得分:1)

为什么你不只是使用像remove-if-not这样的高阶函数?

(defun odds-of (numbers)
    (remove-if-not #'oddp numbers))

(odds-of (loop for x below 10 collect x)) => '(1 3 5 7 9)

lisp社区鼓励使用(和重用)高阶函数,并且过滤'函数通常用于remove-if-notremove-if。检查那些很酷的材料:Filter Function