我尝试将列表中的某个元素E替换为所有主列表级别的另一个列表K.
(defun replaceList(l e k)
(cond
((null l) nil)
((equal e (car l)) (cons k (replaceList (cdr l) e k)))
((listp (car l))
((equal e (car (car l))) (cons k (replaceList (cdr (car l)) e k))))
(t (cons (car l) (replaceList (cdr l) e k)))))
示例:
(replaceList '(3 1 2 (6 1) 7 (5 (5 (3 1))) 9) '1 '(99 99))
--> (3 (99 99) 2 (6 (99 99)) 7 (5 (5 (3 (99 99) ) ) ) 9)
我得到一些lambda表达式作为错误消息。
另外,我试过而不是listp(car l)
"阻止" :
((listp (car l)) (cons k (replaceList (cdr (car l)) e k)))
。
我得到一些奇怪的东西:
(2 1 3 ( 6 1 7) 7 1 2 )
- > (2 (99 99) 3 (99 99) (99 99) 7)
答案 0 :(得分:6)
你的" lambda表达消息"是由于equal
子句中listp
周围有一组额外的parens。请记住,Lisp parentheses are meaningful。
ANSI Common Lisp subst
可以满足您的需求:
(subst '(99 99) 1 '(3 1 2 (6 1) 7 (5 (5 (3 1))) 9) :test #'equal)
==> (3 (99 99) 2 (6 (99 99)) 7 (5 (5 (3 (99 99)))) 9)
由于您在树上操作,而不是列表(您说" 所有
主要列表级别"),您应该同等对待car
和cdr
:
(defun my-subst (new old tree &key (test #'eql))
(cond ((funcall test old tree)
new)
((atom tree)
tree)
(t
(cons (my-subst new old (car tree) :test test)
(my-subst new old (cdr tree) :test test)))))
(my-subst '(99 99) 1 '(3 1 2 (6 1) 7 (5 (5 (3 1))) 9) :test #'equal)
==> (3 (99 99) 2 (6 (99 99)) 7 (5 (5 (3 (99 99)))) 9)
(defun my-subst (new old tree)
(cond ((equal old tree)
new)
((atom tree)
tree)
(t
(cons (my-subst new old (car tree))
(my-subst new old (cdr tree))))))