List Common Lisp:删除具有相同cdr的元素

List Common Lisp:删除具有相同cdr的元素,list,lisp,common-lisp,List,Lisp,Common Lisp,(作业帮助,请放轻松)(我必须在不使用破坏性函数(setf)的情况下执行此操作) 使用common lisp,作为某些代码的一部分,我需要能够: 拿一张清单, 比较两个元素的cdr, 如果相等,则忽略第一个元素, 如果不相等,则尝试将第一个元素与列表中未选中的下一个元素进行比较 需要澄清的一些例子: ((11)(21)(31))->((31)) ((220)(411)(120)(3011)(811))->((120)(3011)(811)) 目前,只有当列表中所有“相似”术语相邻放置时,代码才能

(作业帮助,请放轻松)(我必须在不使用破坏性函数(setf)的情况下执行此操作)

使用common lisp,作为某些代码的一部分,我需要能够:

拿一张清单, 比较两个元素的cdr, 如果相等,则忽略第一个元素, 如果不相等,则尝试将第一个元素与列表中未选中的下一个元素进行比较

需要澄清的一些例子:

((11)(21)(31))->((31))

((220)(411)(120)(3011)(811))->((120)(3011)(811))

目前,只有当列表中所有“相似”术语相邻放置时,代码才能正常工作。

在注释中使用删除重复项可能就是您想要的删除重复项是非破坏性的(参见删除重复项,它可以是破坏性的),并指定为返回一个新列表,其中除了元素的最后一个实例外,其余所有实例都被省略(重点添加):

删除重复项返回序列的修改副本,其中 与顺序中出现的另一个元素匹配的元素已被删除 删除…序列元素成对比较,并且 如果任意两个匹配,则顺序中较早出现的一个为 丢弃,除非“从结束”为真,在这种情况下,后面的 序列被丢弃

您需要指定一个key参数,以指示实际应该比较的是元素的cdr,以及一个test参数,以指示应该与equal进行比较。因此:

(remove-duplicates '((1 1 1) (2 1 1) (3 1 1))
                   :test 'equal 
                   :key 'cdr)
;=> ((3 1 1))


(删除重复项’((11)(21)(31)):key#'cdr:test#'equal)
。只是说。对不起,更新后说我不能使用破坏性函数不是破坏性的,
delete duplicates
是。但是我想您必须自己实现它。您的算法无法工作,因为两个具有相同CDR的子列表在您的列表中不一定是连续的。“如果相等创建忽略第一个元素”是什么意思?
(remove-duplicates '((1 1 1) (2 1 1) (3 1 1))
                   :test 'equal 
                   :key 'cdr)
;=> ((3 1 1))
(remove-duplicates '((2 2 0) (4 1 1) (1 2 0) (3 0 1) (8 1 1))
                   :test 'equal
                   :key 'cdr)
;=> ((1 2 0) (3 0 1) (8 1 1))