我刚刚开始学习 Lisp。我的问题是,每次列表中出现一个项目时,我都试图替换它。我必须使用递归并且没有任何循环来完成此操作。该函数以 (subste x y L)
开头。
示例是:
(subste 7 t '(it is 7)) → (IT IS T)
(subste 7 nil '(7 is not to (7))) → (NIL IS not TO (NIL))
(subste 7 nil '(5 is not (22))) → (5 is not (22))
这是我到目前为止所要做的:
(defun subste (x y L)
(cond ((null L) nil)
((not (= (car L) x))
subste (x y (cdr L)))
((= (car L) x)
(let L 'y))))
我已经多次运行这个程序并对其进行了多次调整,但考虑到错误消息提供的信息很少并且才刚刚开始学习 Lisp,我没有运气。谢谢。
最佳答案
SUBST
已经实现了您想要的行为。您似乎只是希望旧元素和新元素具有不同的顺序,因此一个简单的包装器就可以了:
(defun subste (x y l)
(subst y x l))
如果您想自己实现它,下面是一个简单的版本。注意不同的分支:
- 递归树总是涉及对树的第一个元素进行递归调用,并对树的其余部分进行另一个元素。
- 在树的末尾返回
nil
。 - 如果我们发现要替换的元素,我们就会更改它。
- 对于任何其他原子,我们不需要递归,我们只需返回原子。
这里是例子:
(defun subste (x y l)
(cond ((null l) nil)
((eql l x) y)
((atom l) l)
(T (cons (subste x y (first l))
(subste x y (rest l))))))
此版本不完整:您无法替换非 eql 元素(如字符串或子列表)。您可以添加测试函数作为参数,而不是始终使用 EQL
如果你愿意的话。
关于list - 将项目替换为列表中的每个出现项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33029165/