Lisp - 替换列表中元素的所有外观

Edu*_*ian 2 lisp common-lisp syntax-error

我尝试将列表中的某个元素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)))))
Run Code Online (Sandbox Code Playgroud)

例:

(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)
Run Code Online (Sandbox Code Playgroud)

我得到一些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)

sds*_*sds 6

错误

你的"lambda表达式消息"是由于equallistp子句中有一组额外的parens .请记住,Lisp括号是有意义的.

使用标准库!

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)
Run Code Online (Sandbox Code Playgroud)

你的算法

由于您在树上操作,而不是列表(您说" 所有主列表级别 "),您应该对待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)
Run Code Online (Sandbox Code Playgroud)

或者,简化(没有&keyfuncall):

(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))))))
Run Code Online (Sandbox Code Playgroud)