【问题标题】:Lisp - replace all the appereances of an element in a list [duplicate]Lisp - 替换列表中元素的所有外观[重复]
【发布时间】:2017-12-11 18:10:23
【问题描述】:

我尝试在所有主列表级别将列表中的某个元素 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) "block" : ((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)

【问题讨论】:

  • “我得到一些带有 lambda 表达式的错误信息”——请复制并粘贴确切的错误信息。

标签: syntax-error lisp common-lisp


【解决方案1】:

错误

您的“lambda 表达式消息”是由于 listp 子句中 equal 周围的一组额外括号。记住,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)

你的算法

由于您是在 tree 上操作,而不是 list(您说“所有 主列表级别"),您应该同等对待carcdr

(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)

或者,简化(没有&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))))))

【讨论】:

  • 你好,@sds。谢谢您的回答。但是我的代码没有任何可能的修改以使其工作吗?我们的教授坚持不使用像“subst”这样的标准库函数(是的,我知道,这有点奇怪,但我认为她想让我们理解这背后的算法......)。谢谢你帮助链接也:)
  • @EduardAdrian:my-subst 不是您要找的吗?当然,您可以更改参数的顺序。让我重申一下:如果你没有对称地使用carcdr,那么你做的不是正确的。
  • 可能是,但我不了解 &key (test #'eql) 和 funcall 结构。我们处于非常基础的水平,我想我们稍后会了解。这就是为什么我要求一种非常简单的方法来解决这个问题。
  • @EduardAdrian:我添加了一个简化版本。
猜你喜欢
  • 2021-01-13
  • 2014-08-03
  • 1970-01-01
  • 2018-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-28
相关资源
最近更新 更多