Error handling 如何在不使用LISP中的remove函数的情况下从列表中删除元素
我试图编写一个函数来从列表中删除一个元素,但我得到一个错误,即“应该是lambada函数”,我不知道我的代码是正确的还是错误的。您的代码有问题 您的代码有一些问题。首先,让我们看一下标准缩进Error handling 如何在不使用LISP中的remove函数的情况下从列表中删除元素,error-handling,lisp,Error Handling,Lisp,我试图编写一个函数来从列表中删除一个元素,但我得到一个错误,即“应该是lambada函数”,我不知道我的代码是正确的还是错误的。您的代码有问题 您的代码有一些问题。首先,让我们看一下标准缩进 (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))
(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))
)))))
每个标记行都有一个问题。Lisp中函数调用的语法为
(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)
这意味着在您的(i)
行中,您试图调用一个名为(setf x car(list1))
的函数,该函数带有一个参数(if(!=xe)
)。当然,这不是函数的名称,我怀疑即使它是,您也不想用参数(if(!=xe)…
调用它。同样地
(function argument…)
正在尝试将x
设置为变量car
的值(并且没有),然后将新值分配给位置(列表1)
。由于函数调用的语法是(函数参数…
),因此您需要:
(setf x car (list1))
如果您试图对窗体进行排序,您可以考虑使用,在其中可以提供多个表单,或者<代码> PRONN/<代码>(参见)。 例如,而不是
(setf x (car list1))
你可能想要
((my_append e list2 ) ; (ii)
(setf y cdr(list1)) ; (iii)
(my_remove(e y list2))) ; (iv)
不过,你也会遇到一些问题。在(iii)
和(iv)
中,您需要使用(cdr list 1)
和(my_remove e y list 2)
,如上所述,但您也有一个问题,即您正在评估(ii)
和(iii)
,但您正在丢弃该值
简化方法
我认为如果您考虑一下my remove
的简单定义,可能会对您有利。通常,列表是空列表()
或cons单元格,其car是列表的第一个元素,其cdr是列表的其余部分。您可以使用这样的定义,然后:
- 删除(x,列表)
- 若列表是空的,那个么返回列表(它是空的,所以它肯定不包含x)
- 如果列表不是空的,则
- 如果列表的第一个元素是x,则返回remove(x,rest(list))
- 否则,列表的第一个元素不是x,因此返回一个新列表,其第一个元素是列表的第一个元素,其余元素是remove(x,rest(list))
(progn
(my_append e list2 ) ; (ii)
(setf y cdr(list1)) ; (iii)
(my_remove(e y list2))) ; (iv)
那些嵌套的if
s看起来有点难看,您可能希望在此处使用cond
,即使您不需要它允许的多个表达式体:
CL-USER> (my-remove 1 '(1 2 3 1 2 3))
(2 3 2 3)
由于没有主体的cond
子句(其测试表单的计算结果为true)返回测试表单的值,因此您甚至可以将最后一个子句简化一点:
(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))))))
正确的格式将有很大帮助(这不是一个尖刻的评论;很难仅从parens来区分语法缩进问题!)我是这里的初学者,我不知道正确的缩进,我尝试了我在上面写的任何东西。如果你能使用一个支持Lisp的编辑器,例如Emacs或内置在IDE中的编辑器,它将对你有很大帮助(例如,Lispworks的编辑).vim也了解Lisp语法。你是从课堂上还是从教科书上学习的?代码中有一些非常基本的语法问题。几个Lisp示例函数可以清楚地说明这一点。我认为你应该离线整理其中的一些,然后再做一次尝试。对不起,实际上我正在尝试设置“x”中的“list1”What is list*and What is endp?@user39495在这里它可以被
cons
替换,但是list*
类似于list
,除了最后一个参数是结果列表的尾部。例如(list*12'(34 5));=>(1 2 3 4 5)endp
是null
的同义词@user39495 Sylwester的答案是正确的。我喜欢使用endp
/首先//
/列表*
来强调我们在这里使用的是列表,而不是cons
单元格的树。不过,这些问题很容易用快速的Goo来回答gle搜索,或者更具体地说,lispdoc.com上的搜索,例如。list*
,搜索起来有点困难,但它与。
(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))))))
(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))))))