Recursion 如何在公共lisp中编写一个查找所有奇数的函数?

Recursion 如何在公共lisp中编写一个查找所有奇数的函数?,recursion,iteration,common-lisp,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在不递归的情况下重写它?一种方法是在do中累积

下面是我的函数,它返回列表中的所有奇数:

(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
在不递归的情况下重写它?

一种方法是在
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),所以重复追加会导致二次时间复杂度。

为什么不使用高阶函数,如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 not
remove if
。检查一下那个很酷的材料:

是的,这是图雷茨基书中的练习11.9。你试图解决什么问题?你的实际问题是什么?