Lisp 从嵌套列表中删除
我有一个作业把我难住了!我必须创建一个函数goo(ALL),它将删除L中的每个a,并且它还必须处理嵌套列表 这是我到目前为止得到的Lisp 从嵌套列表中删除,lisp,common-lisp,Lisp,Common Lisp,我有一个作业把我难住了!我必须创建一个函数goo(ALL),它将删除L中的每个a,并且它还必须处理嵌套列表 这是我到目前为止得到的 (defun goo(A L) (cond ((null L) nil) ; if list is null, return nil (T ; else list is not null (cond ((atom (car L))) ;if car L is an atom ((cond ((equal A (car L)) (goo A
(defun goo(A L)
(cond ((null L) nil) ; if list is null, return nil
(T ; else list is not null
(cond ((atom (car L))) ;if car L is an atom
((cond ((equal A (car L)) (goo A (cdr L))) ;if car L = A, call goo A cdr L
(T (cons (car L) (goo A (cdr L)))))) ;if car L != A,
(T (cons (goo A (car L)) (goo A (cdr L)))))) ;else car L is not atom, call goo on car L and call goo on cdr L
))
不管我给它什么,这个函数都返回True。你的父母都搞砸了。将最后一个参数在
(atom(car L))
周围移动,以包含下一个cond
表达式。我建议使用显示匹配参数的IDE
至于造型,如果你不知道。这样,您就不需要再次使用t
和cond
。如果您只测试一个谓词,并且仅基于该谓词做出决策,那么您也可以这样做
注意:这最初是由最初的提问者在中作为问题的编辑发布的
我尝试了另一种方法,它现在起作用了
(defun goo(A L)
(cond ((null L) nil)
((atom (car L)) (cond ((equal A (car L)) (goo A (cdr L)))
(T (cons (car L) (goo A (cdr L))))))
(T (cons (goo A (car L)) (goo A (cdr L))))
))
注2:常规格式应如下所示,以显示程序结构:
我认为这可能更容易被视为一个替代树木的问题。定义一个函数很容易,它采用一棵树并替换其中满足测试要求的子树。有一个标准函数可以做到这一点,但它用相同的东西替换每个匹配的子树。如果我们将元素替换为从子树计算的值,则对我们更有用:
(defun %subst-if (new test tree)
"Replace subtrees of TREE that satisfy TEST with the result
of calling NEW with the subtree."
(cond
;; If tree satifies the test, return (new tree).
((funcall test tree)
(funcall new tree))
;; If tree is a cons, recurse.
((consp tree)
(cons (%subst-if new test (car tree))
(%subst-if new test (cdr tree))))
;; Otherwise, just return the leaf.
(tree)))
有了它,就可以很容易地定义我们需要的函数类型。当一个元素X出现在嵌套列表结构中的某个位置时,这意味着有一个cons单元的car是X。我们希望用它的cdr替换该cons单元,但也要在该单元的cdr上递归。这并不难:
(defun replace* (x list &key (test 'eql))
"Remove occurrences of X in LIST and its sublists."
(%subst-if
(lambda (cons)
"Replace elements of the form (X . more) with
(replace* x more :test test)."
(replace* x (cdr cons) :test test))
(lambda (subtree)
"Detect subtrees of the form (X . more)."
(and (consp subtree)
(funcall test x (car subtree))))
list))
谢谢你,伙计。移动参数给了我一个错误,但我尝试了另一种使用cond multiple子句的方法,并使其起作用。如果您找到了适合您的解决方案,请不要将其编辑到问题中,而是将其作为答案发布,并将其标记为已接受。目前,我已将其复制到社区维基答案中,并将其从问题中删除。尽管如此,请随意发布您自己的答案,我将删除CW答案。
(defun replace* (x list &key (test 'eql))
"Remove occurrences of X in LIST and its sublists."
(%subst-if
(lambda (cons)
"Replace elements of the form (X . more) with
(replace* x more :test test)."
(replace* x (cdr cons) :test test))
(lambda (subtree)
"Detect subtrees of the form (X . more)."
(and (consp subtree)
(funcall test x (car subtree))))
list))
(replace* 'a '(1 a (2 a 3) a 4 a 5))
;=> (1 (2 3) 4 5)