这是我的功能,它从列表中返回所有奇数:
(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
重写它?
答案 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-not
和remove-if
。检查那些很酷的材料:Filter Function