2

我正在尝试编写一个返回列表中原子列表的函数,可以说我有一个列表,其中既有原子又有一个列表,当我运行该函数时,它应该返回一个原子列表。

例如:

(func '(2 34 5 (12) 7 (A B C) +))
 -> (2 34 7 +)

我想尝试结果中的参数是否为真,这样当我运行时:

(ATOM ( (func '(2 34 5 (12) 7 (A B C) +)) )
->T

关于我如何去做的任何想法?书籍或参考资料?

4

2 回答 2

3

使用标准 CL 函数,

[3]> (remove-if-not #'atom '(1 2 (12) +))
(1 2 +)

[6]> (every #'atom (remove-if-not #'atom '(1 2 (12) +)))
T

如果您想自己编写它们,您可以融合#'atomin 并制作两个专门的函数,比如remove-atomsand every-is-atom。但是“原子”是一个内置函数atom的名称。

写第一个的一种方法是

(defun remove-atoms (xs &aux (ys (list 1)))
  (let ((p ys))
    (dolist (x xs (cdr ys))
      (if (atom x) (setf (cdr p) (list x) p (cdr p))))))

这使用破坏性更新以自上而下的方式构建结果列表,这并不违反这里的函数式编程精神,因为它是在本地使用的,作为一种实现技术。这可以看作是来自其他答案的通用函数尾递归模数代码的 Common-LISP 特定翻译。

第二个功能:

(defun every-is-atom (xs)
  (dolist (x xs T)
    (if (not (atom x)) 
      (return-from every-is-atom NIL))))
于 2012-10-21T09:43:26.893 回答
2

所以你想要一个只返回作为参数传递的列表中存在的原子值的函数?

像这样?

(defun func (lst)
  (cond 
    ((null lst) '()) 
    ((atom (first lst)) 
     (cons (first lst) (func (rest lst)))) 
    (t (func (rest lst)))))

不是专门针对 Common lisp,但在我看来仍然是一本好书:SICP

于 2012-10-21T09:30:48.733 回答