我正在尝试编写一个函数(深度查找),它接受一个列表和另一个参数,如果列表中存在该参数,则返回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))))
答案 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提供了一些负责遍历树的函数:
是列表上的函数的等价物:
此处: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))
)
)
)