gpt4 book ai didi

error-handling - 如何在不使用 LISP 中的 remove 函数的情况下从列表中删除元素

转载 作者:太空宇宙 更新时间:2023-11-03 19:04:30 25 4
gpt4 key购买 nike

  (defun my_remove(e list1 list2)
(if (null list1)
nil
((setf x car(list1))
(if (!= x e)
((my_append e list2 )
(setf y cdr(list1))
(my_remove(e y list2)))

((setf y cdr(list1))
(my_remove(e y list2))
)))))

我正在尝试编写一个函数来从列表中删除一个元素,但出现“它应该是 lambada 函数”的错误,我不知道我的代码是正确的还是错误的。

最佳答案

你的代码有问题

您的代码存在一些问题。先来看标准缩进

(defun my_remove(e list1 list2)
(if (null list1)
nil
((setf x car(list1)) ; (i)
(if (!= x e)
((my_append e list2 ) ; (ii)
(setf y cdr(list1)) ; (iii)
(my_remove(e y list2))) ; (iv)
((setf y cdr(list1)) ; (v)
(my_remove(e y list2))))))) ; (vi)

标记的每一行都有问题。 Lisp 中函数调用的语法是

(function argument…)

这意味着在你的行 (i) 中,你试图调用一个名为 (setf x car(list1)) 的函数,参数 (if (!= x e) …)。当然,这不是函数的名称,我怀疑即使是,您也不想使用参数 (if (!= x e) …) 调用它。同样

(setf x car (list1))

试图将 x 设置为变量 car 的值(实际上没有),然后将新值赋给放置 (list1)。由于函数调用的语法是 (function argument...),因此您需要:

(setf x (car list1))

如果您尝试对表格进行排序,您可以考虑使用 cond ,您可以在其中提供多种形式,或 progn(参见 In Common Lisp, why do multi-expression bodies of (if) statements require (progn)?)。

例如,代替

           ((my_append  e list2 )            ; (ii)
(setf y cdr(list1)) ; (iii)
(my_remove(e y list2))) ; (iv)

你可能想要

           (progn
(my_append e list2 ) ; (ii)
(setf y cdr(list1)) ; (iii)
(my_remove(e y list2))) ; (iv)

不过,您也会遇到一些问题。在 (iii)(iv) 中,您需要使用 (cdr list1)(my_remove e y list2),如上所述,但您也遇到了正在评估 (ii)(iii) 的问题,但您正在丢弃该值。

简化的方法

我认为如果您考虑my-remove 的简单定义,可能对您有利。通常,列表要么是空列表 (),要么是一个 cons 单元格,其 car 是列表的第一个元素,其 cdr 是列表的其余部分。您可以使用这样的定义,然后:

  • 删除(x,列表)
    • 如果list为空,则返回list(为空,肯定不包含x)
    • 如果列表不为空,则
      • 如果列表的第一个元素是x,则返回remove(x,rest(list))
      • 否则,列表的第一个元素不是 x,因此返回一个新列表,其第一个元素是列表的第一个元素,其余元素是 remove(x,rest(list))。

在代码中,它看起来像:

(defun my-remove (element list)
(if (endp list)
list
(if (eql element (first list))
(my-remove element (rest list))
(list* (first list)
(my-remove element (rest list))))))
CL-USER> (my-remove 1 '(1 2 3 1 2 3))
(2 3 2 3)

那些嵌套的 if 看起来有点难看,你可能想在这里使用 cond,即使你不需要它允许的多个表达式主体:

(defun my-remove (element list)
(cond
((endp list)
list)
((eql element (first list))
(my-remove element (rest list)))
(t
(list* (first list) (my-remove element (rest list))))))

由于 cond 子句没有主体,其测试形式的计算结果为 true 返回测试形式的值,您甚至可以使最后一个子句更简单一些:

(defun my-remove (element list)
(cond
((endp list) list)
((eql element (first list)) (my-remove element (rest list)))
((list* (first list) (my-remove element (rest list))))))

关于error-handling - 如何在不使用 LISP 中的 remove 函数的情况下从列表中删除元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23061447/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com