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))))

そして、名前が示すように、不自然なソリューションですが、(!) は 1 回のパスで実行します。

(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 に答える