鍍金池/ 教程/ Java/ LISP - 集合
LISP - 樹
LISP - 錯誤處理
LISP - 謂詞
LISP - 決策
LISP - 變量
LISP - 數(shù)組
LISP - 對象系統(tǒng)(CLOS)
LISP - 輸入和輸出
Lisp教程
LISP - 數(shù)字
LISP - 循環(huán)
LISP - 常量
LISP - 集合
LISP - 字符
LISP - 程序結(jié)構(gòu)
LISP - 文件I/O
LISP - 哈希表
LISP - 宏
LISP - 數(shù)據(jù)類型
LISP - 包
LISP - 符號
LISP - 運(yùn)算符
LISP - 基本語法
LISP - 函數(shù)
LISP - 向量
LISP - 結(jié)構(gòu)
LISP - 概述介紹

LISP - 集合

Common Lisp不提供的一組數(shù)據(jù)類型。然而,它提供的函數(shù)數(shù)量,它允許一組操作,以可以在列表上執(zhí)行。

可以添加,刪除和搜索列表中的項目,根據(jù)不同的標(biāo)準(zhǔn)。還可以執(zhí)行像不同的集合運(yùn)算:并,交和集合差。

實現(xiàn)LISP集合

集合像列表一樣,一般實現(xiàn)的利弊單元。由于這個原因,集合操作越來越少,高效的獲取大的集合。要明白這一點(diǎn),一旦我們深入研究這個問題更深一點(diǎn)。

adjoin函數(shù)可建立一個集合。這需要一個條目和一個列表表示一組,并返回表示包含該項目,并在原設(shè)定的所有項目的集合列表。

adjoin函數(shù)首先查找的條目給定列表中,一旦找到,將返回原來的名單;否則,創(chuàng)建一個新的cons單元,其car作為該目條,cdr指向原來的列表并返回這個新列表。

該毗函數(shù)也需要:key 和 :test關(guān)鍵字參數(shù)。這些參數(shù)用于檢查該條目是否存在于原始列表。

因為,adjoin函數(shù)不會修改原來的列表,讓列表本身的變化,必須指定由adjoin到原始列表返回的值或者可以使用宏pushnew將條目添加到集合。

示例

創(chuàng)建一個名為main.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)
(setf *myset* (adjoin 1 *myset*))
(setf *myset* (adjoin 2 *myset*))
;now the original set is changed
(write *myset*)
(terpri)
;adding an existing value
(pushnew 2 *myset*)
;no duplicate allowed
(write *myset*)
(terpri)
;pushing a new value
(pushnew 3 *myset*)
(write *myset*)
(terpri)

當(dāng)執(zhí)行代碼,它返回以下結(jié)果:

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

檢查成員

函數(shù)的成員組允許檢查一個元素是否是一個集合成員。

以下是這些函數(shù)的語法:

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

這些函數(shù)搜索給定列表中一個給定的項,滿足了測試。它沒有這樣的項被找到,則函數(shù)返回nil。否則,將返回列表中的元素作為第一個元素的尾部。

搜索是只在頂層進(jìn)行。

這些函數(shù)可作為謂詞。

示例

創(chuàng)建一個名為main.lisp一個新的源代碼文件,并在其中輸入如下代碼:

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

當(dāng)執(zhí)行代碼,它返回以下結(jié)果:

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

集合聯(lián)合

聯(lián)合組功能能夠在作為參數(shù)提供給這些功能測試的基礎(chǔ)上,兩個列表進(jìn)行集聯(lián)合。

以下是這些函數(shù)的語法:

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

union函數(shù)有兩個列表,并返回一個包含所有目前無論是在列表中的元素的新列表。如果有重復(fù),則該成員只有一個副本被保存在返回的列表。

union函數(shù)執(zhí)行相同的操作,但可能會破壞參數(shù)列表。

示例

創(chuàng)建一個名為main.lisp一個新的源代碼文件,并在其中輸入如下代碼:

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

當(dāng)執(zhí)行代碼,它返回以下結(jié)果:

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

請注意:

對于三個向量列表 :test-not #'不匹配的參數(shù):如預(yù)期的union函數(shù)不會工作。這是因為,該名單是由cons單元元素,雖然值相同的外觀明顯,單元元素cdr部分不匹配,所以他們并不完全一樣,以LISP解釋器/編譯器。這是原因;實現(xiàn)大集全不建議使用的列表。它工作正常的小集合上。

交集

函數(shù)的交點(diǎn)組允許作為參數(shù)提供給這些函數(shù)測試的基礎(chǔ)上,兩個列表進(jìn)行交點(diǎn)。

以下是這些函數(shù)的語法:

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

這些函數(shù)需要兩個列表,并返回一個包含所有目前在這兩個參數(shù)列表中的元素的新列表。如果任一列表中的重復(fù)項,冗余項可能會或可能不會出現(xiàn)在結(jié)果中。

示例

創(chuàng)建一個名為main.lisp一個新的源代碼文件,并在其中輸入如下代碼:

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

當(dāng)執(zhí)行代碼,它返回以下結(jié)果:

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

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

差集

set-difference組差集,可以在作為參數(shù)提供給這些功能測試的基礎(chǔ)上,兩個列表進(jìn)行差集。

以下是這些函數(shù)的語法:

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

set-difference函數(shù)返回,不會出現(xiàn)在第二個列表的第一個列表的元素的列表。

示例

創(chuàng)建一個名為main.lisp一個新的源代碼文件,并在其中輸入如下代碼:

(setq set1 (set-difference 上一篇:LISP - 循環(huán)下一篇:LISP - 錯誤處理