# LISP - 集合

Common Lisp不提供的一組數據類型。然而，它提供的函數數量，它允許一組操作，以可以在列表上執行。

## 實現LISP集合

; creating myset as an empty list (defparameter *myset* ()) (adjoin 1 *myset*) (adjoin 2 *myset*) ; adjoin didn't change the original set
;so it remains same
(write *myset*)
(terpri)
;now the original set is changed
(write *myset*)
(terpri)
(pushnew 2 *myset*)
;no duplicate allowed
(write *myset*)
(terpri)
;pushing a new value
(pushnew 3 *myset*)
(write *myset*)
(terpri)

NIL (2 1) (2 1) (3 2 1)

## 檢查成員

member item list &key :test :test-not :key
member-if predicate list &key :key
member-if-not predicate list &key :key

(write (member 'zara '(ayan abdul zara riyan nuha))) (terpri) (write (member-if #'evenp '(3 7 2 5/3 'a))) (terpri) (write (member-if-not #'numberp '(3 7 2 5/3 'a 'b 'c)))

(ZARA RIYAN NUHA) (2 5/3 'A)
('A 'B 'C)

## 集合聯合

union list1 list2 &key :test :test-not :key
nunion list1 list2 &key :test :test-not :key

union函數有兩個列表，並返回一個包含所有目前無論是在列表中的元素的新列表。如果有重複，則該成員只有一個副本被保存在返回的列表。

union函數執行相同的操作，但可能會破壞參數列表。

(setq set1 (union '(a b c) '(c d e))) (setq set2 (union '(#(a b) #(5 6 7) #(f h))
'(#(5 6 7) #(a b) #(g h)) :test-not #'mismatch)) (setq set3 (union '(#(a b) #(5 6 7) #(f h))
'(#(5 6 7) #(a b) #(g h)))) (write set1) (terpri) (write set2) (terpri) (write set3)

(A B C D E) (#(F H) #(5 6 7) #(A B) #(G H)) (#(A B) #(5 6 7) #(F H) #(5 6 7) #(A B) #(G H))

## 交集

intersection list1 list2 &key :test :test-not :key
nintersection list1 list2 &key :test :test-not :key

(setq set1 (intersection '(a b c) '(c d e))) (setq set2 (intersection '(#(a b) #(5 6 7) #(f h))
'(#(5 6 7) #(a b) #(g h)) :test-not #'mismatch)) (setq set3 (intersection '(#(a b) #(5 6 7) #(f h))
'(#(5 6 7) #(a b) #(g h)))) (write set1) (terpri) (write set2) (terpri) (write set3)

(C) (#(A B) #(5 6 7)) NIL

intersection 函數是相交的破壞性版本，也就是說，它可能會破壞原始列表。

## 差集

set-difference組差集，可以在作爲參數提供給這些功能測試的基礎上，兩個列表進行差集。

set-difference list1 list2 &key :test :test-not :key
nset-difference list1 list2 &key :test :test-not :key

set-difference函數返回，不會出現在第二個列表的第一個列表的元素的列表。

(setq set1 (set-difference '(a b c) '(c d e))) (setq set2 (set-difference '(#(a b) #(5 6 7) #(f h))
'(#(5 6 7) #(a b) #(g h)) :test-not #'mismatch)) (setq set3 (set-difference '(#(a b) #(5 6 7) #(f h))
'(#(5 6 7) #(a b) #(g h)))) (write set1) (terpri) (write set2) (terpri) (write set3)

(A B) (#(F H)) (#(A B) #(5 6 7) #(F H))