修复删除元素的函数 [Common Lisp]
fix the function which removes elments [Common Lisp]
任务是:对于给定的元素列表和 X 元素,如果不等于 X,则删除 X 之后的元素。示例:(a 8 2 a a 5 a) X=a,期望 (a 2 a a a ).
我有删除元素 before X 的代码,所以它给了我 (a 8 a a a)。我该如何解决?
(defun purgatory (n w)
(cond ((null w) nil)
((and (eq (cadr w) n) (not (eq (car w) (cadr w)))) (purgatory n (cdr w)))
((cons (car w) (purgatory n (cdr w))))))
我认为您使用递归算法是正确的。我认为该算法作为 tail-optimised 递归效果更好。你拿一个 in-list
和一个 X
,然后建立一个 out-list
。输出是相反的,所以最后需要应用reverse
,因此:
(defparameter my-list '(a 8 2 a a 5 a))
(defun remove-after (in-list X &optional (out-list '()) (last '()))
(if (null in-list)
(reverse out-list)
(if (and (eql last X) (not (eql (car in-list) X)))
(remove-after (cdr in-list) X out-list (car in-list))
(remove-after (cdr in-list) X (cons (car in-list) out-list) (car in-list))
)))
; (A 2 A A A)
至于non-tail算法,我觉得是这样的:
(defun purgatory (n w)
(cond ((null w) nil)
((and (eq (car w) n) (not (eq n (cadr w)))) (cons (car w) (purgatory n (cddr w))))
(t (cons (car w) (purgatory n (cdr w))))
))
; (A 2 A A A)
因此,如果第一个元素是n
而下一个元素不是n
,则在算法的前面添加n
,但跳过cddr
下一个元素。否则,将第一个元素添加到算法前面,不跳过cdr
.
注意:既然你已经根据 X
定义了问题,我认为这应该是你的参数之一,而不是 n
您可以在 loop
中使用 for on
子句的解构:
(defun purgatory (list x)
(cons (first list)
(loop :for (a b) :on list
:unless (and (eql a x)
(not (eql b x)))
:collect b)))
任务是:对于给定的元素列表和 X 元素,如果不等于 X,则删除 X 之后的元素。示例:(a 8 2 a a 5 a) X=a,期望 (a 2 a a a ). 我有删除元素 before X 的代码,所以它给了我 (a 8 a a a)。我该如何解决?
(defun purgatory (n w)
(cond ((null w) nil)
((and (eq (cadr w) n) (not (eq (car w) (cadr w)))) (purgatory n (cdr w)))
((cons (car w) (purgatory n (cdr w))))))
我认为您使用递归算法是正确的。我认为该算法作为 tail-optimised 递归效果更好。你拿一个 in-list
和一个 X
,然后建立一个 out-list
。输出是相反的,所以最后需要应用reverse
,因此:
(defparameter my-list '(a 8 2 a a 5 a))
(defun remove-after (in-list X &optional (out-list '()) (last '()))
(if (null in-list)
(reverse out-list)
(if (and (eql last X) (not (eql (car in-list) X)))
(remove-after (cdr in-list) X out-list (car in-list))
(remove-after (cdr in-list) X (cons (car in-list) out-list) (car in-list))
)))
; (A 2 A A A)
至于non-tail算法,我觉得是这样的:
(defun purgatory (n w)
(cond ((null w) nil)
((and (eq (car w) n) (not (eq n (cadr w)))) (cons (car w) (purgatory n (cddr w))))
(t (cons (car w) (purgatory n (cdr w))))
))
; (A 2 A A A)
因此,如果第一个元素是n
而下一个元素不是n
,则在算法的前面添加n
,但跳过cddr
下一个元素。否则,将第一个元素添加到算法前面,不跳过cdr
.
注意:既然你已经根据 X
定义了问题,我认为这应该是你的参数之一,而不是 n
您可以在 loop
中使用 for on
子句的解构:
(defun purgatory (list x)
(cons (first list)
(loop :for (a b) :on list
:unless (and (eql a x)
(not (eql b x)))
:collect b)))