簡體   English   中英

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

[英]Common Lisp: Removing elements with the same cdr

(分配幫助,請放心)(我必須在不使用破壞性函數(setf)的情況下執行此操作)

使用通用Lisp,作為某些代碼的一部分,我需要能夠:

取得列表列表,比較2個元素的cdr;如果相等,則忽略第一個元素;如果不相等,則嘗試將第一個元素與列表中的下一個未經檢查的元素進行比較。

一些例子可以澄清:

(((1 1 1)(2 1 1)(3 1 1))->(((3 1 1)))

((2 2 0)(4 1 1)(1 2 0)(3 0 1)(8 1 1))->(((1 2 0)(3 0 1)(8 1 1))

(defun simplify2 (vari)
    ;If last term: stop
    (if (equal (cdr vari) nil) vari

        ;If cdr of first and second term are equal...
        (if (equal (cdar vari) (cdr (cadr vari)))

            ;Ignore the first term and continue with the rest of the list
            (simplify2 (cdr vari))

            ;Otherwise (this is the line which isn't working)
            (cons (car vari) (simplify2 (cdr vari))))))

目前,只有當所有“喜歡”字詞在列表中並排放置時,代碼才能正常工作。

Le Petit Prince在評論中建議使用刪除重復項可能是您想要的。 remove-duplicates是非破壞性的(請參閱delete-duplicates可能是破壞性的),它被指定為返回一個新列表,其中省略了除元素的最后一個實例之外的所有其他元素(添加了強調):

刪除重復項

remove-duplicates返回序列的修改后的副本,已從該序列中刪除了與按順序出現的另一個元素匹配的任何元素。 …對序列的元素進行成對比較,如果有兩個匹配,則丟棄序列中較早出現的一個 ,除非from-end為true,在這種情況下,序列中較晚的一個被丟棄。

您需要指定一個key參數來指示實際上應該比較的是元素的cdr ,以及一個test參數來指示應該將它們與equal比較。 從而:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM