1

几天前我学习了lisp,我想做的就像下面这样

1`(1 2 3 4 1 5) ==> (2 3 4 1 5)

我能做的是删除所有的出现,我不知道如何保留最后一个符号。

这是我的代码

(defun test (X L)
  (cond ((null L) nil)
        ((equal X (last L)) (test X (butlast L)))    
        (t (cons (test X (butlast L)) (last L)))))

感谢您阅读我的问题!

4

3 回答 3

4

如果这不仅仅是递归中的练习或作业:

(defun remove-all-but-last (element list)
  (remove element list :count (1- (count element list))))

或者:

(defun remove-all-but-last (element list)
  (remove element list :end (position element list :from-end t)))
于 2012-10-10T23:59:57.837 回答
3

相同,但在线性时间内:)

(defun remove-all-but-last (list element)
  (reverse
   (remove-if
    ((lambda (x)
       #'(lambda (y)
           (when (equal y element)
             (if x t (not (setf x t)))))) nil)
    (reverse list))))

而且,顾名思义,这是一个人为的解决方案,但是 (!) 一次性完成。

(defun remove-all-but-last-contrieved
    (list element &optional (test #'equal))
  (do ((c list (cdr c))
        constructed
        back-ref
        last
        last-seen)
       ((null c) back-ref)
    (if back-ref
        (setf last constructed
              (cdr constructed) (list (car c))
              constructed (cdr constructed))
        (setf constructed (list (car c))
              back-ref constructed))
    (when (funcall test (car c) element)
      (if (or last-seen last)
          (when last-seen
            (rplacd last-seen (cddr last-seen)))
          (setf back-ref nil constructed nil))
      (setf last-seen last))))
于 2012-10-10T23:45:58.030 回答
1

给你,递归,但不是很有效的解决方案:

(defun remove-all-but-last (X L)
    (cond ((null L) nil)
           ((equal X (car L)) 
               (if (member X (cdr L)) 
                   (remove-all-but-last X (cdr L)) 
                   L)) 
           (t (cons (car L) (remove-all-but-last X (cdr L))))))
于 2012-10-10T23:08:36.837 回答