如果Atom在列表中,则返回True的LISP函数

时间:2015-02-10 05:18:56

标签: list recursion lisp common-lisp

我正在尝试编写一个函数(深度查找),它接受一个列表和另一个参数,如果列表中存在该参数,则返回T.例如,如果我调用(deep-find '(A B (C D)) 'C)它应该返回true,但是如果我调用(deep-find '(A B (C D)) 'F)它应该返回false。这是我到目前为止的代码,但每次都返回nil:

(defun deep-find (L n)
  (cond
   ((null L) nil)
   ((equal n (car L)) t)
   ((deep-find (cdr L) n))))

5 个答案:

答案 0 :(得分:5)

您的代码每次都不会返回NIL ;它适用于简单列表。例如,(deep-find '(A B (C D)) 'A)会返回T

您的cond中有三种情况:列表末尾,列表头检查和列表尾部检查。但是, trees 中没有任何内容。因此,如果树中存在分支,则需要另一个条件,即递归到树的更深层次:

(defun deep-find (L n)
  (cond
   ((null L) nil)
   ((equal n (car L)) t)
   ((listp (car L))             ; in case of a branch,
    (or (deep-find (car L) n)   ; check the branch,
        (deep-find (cdr L) n))) ; and check rest of the list
   ((deep-find (cdr L) n))))

答案 1 :(得分:3)

你所谓的列表实际上是二叉树。在Common Lisp中,list被定义为head和tail,而tree由car和cdr组成,它们是节点的子节点。请注意,该列表是树的特例。

Common Lisp提供了一些负责遍历树的函数:

  • #'SUBST
  • #'SUBST-如果
  • #'等于树

是列表上的函数的等价物:

  • #'替代
  • #'替代-如果
  • #'等于

此处:http://lisptips.com/post/43404489000/the-tree-walkers-of-cl您可能会找到原始提示。据此,以下代码可以解决您的问题:

(defun deep-find (lst elt)
  (prog1 nil
    (subst-if t (constantly nil) lst
              :key (lambda (x)
                     (when (eql elt x)
                       (return-from deep-find t))))))

答案 2 :(得分:3)

如果您添加更多灵活性,有时这种问题会变得更容易。

例如,考虑通用二叉树而不仅仅是列表(这是二叉树的特定子案例),并假设(deep-find 'a 'a)的正确答案应为T,代码会变短,更优雅:

(defun deep-find (tree item)
  (or (equal tree item)
      (and (consp tree)
           (or (deep-find (car tree) item)
               (deep-find (cdr tree) item)))))

答案 3 :(得分:2)

还有一种方式,

(defun deep-see (lis arg)
 (let ((result))
  (cond
   ((not (null lis))
    (loop for item in lis do
     (cond
      ((not (equal item arg))
       (cond ((listp item) (setf result (deep-see item arg)))))
      ((equal item arg) (setf result t))))))
  result))

用法:(deep-see '(a v c (e (c (((d)))) f)) 'd) => Ť

(deep-see '(a v c (e (c (((d e)))) f)) '(d e)) => Ť

答案 4 :(得分:0)

您可以简单地执行以下操作:

(defun deep-find (expr list)
(cond 
    ((equal list expr) t)
    ((not (atom list)) 
        (or 
            (deep-find expr (car list))
            (deep-find expr (cdr list))
        )
    )
)