📜  LISP 中的集合

📅  最后修改于: 2022-05-13 01:55:28.274000             🧑  作者: Mango

LISP 中的集合

集合是项目的无序集合。集合就像其他数据结构一样。在 C++ 中,我们有一个类似的数据结构,称为哈希映射。 Common lisp 不提供内置的集合数据类型,但它提供了许多允许对列表执行集合操作的函数。使用它们,我们可以在列表中添加和删除项目,还可以检查列表中是否存在项目。我们还可以对列表进行并、交、差运算。

在 Lisp 中实现集合:

集合是使用adjoin函数实现的。 Adjoin函数允许我们建立一个集合。 Adjoin函数可以将列表作为参数并返回一个集合。邻接函数定义如下:

句法:

adjoin item list &key key test  => new-list

这里,item 是一个对象,list 是一个正确的列表,test 是一个有两个参数的函数的指示符,它返回一个布尔值,key 是一个有一个参数的函数的指示符函数。

这些键和测试参数用于检查列表中是否存在项目。如果该项目存在于列表中,则该项目不会添加到集合中。如果该项目不在列表中,则将该项目添加到集合中。如果集合中不存在该项目,我们可以使用宏pushnew将项目添加到集合中,并使用 DELETE 或 REMOVE 删除或删除该项目。

例子:

创建一个新的 lisp 文件并将其保存为set.lisp

Lisp
;; Implementing the Sets in the Lisp
  
(defparameter *mynewset* ()) ;; empty set
(adjoin 1 *mynewset*) ;; *mynewset* is now (1)
(adjoin 2 *mynewset*) ;; *mynewset* is now (1 2)
  
; adjoin did not change the original set
; so it remains same
(write *mynewset*) ;; (1 2)
(terpri) ;; prints a new line
(setf *mynewset* (adjoin 1 *mynewset*)) ;; *mynewset* is now (1)
(setf *mynewset* (adjoin 2 *mynewset*)) ;; *mynewset* is now (1 2)
  
; adding an existing value
(pushnew 2 *mynewset*) ;; *mynewset* is now (1 2)
  
; no duplicate allowed
(write *mynewset*) ;; (1 2)
(terpri) ;; prints a new line
  
; pushing a new value
(pushnew 3 *mynewset*) ;; *mynewset* is now (1 2 3)
(write *mynewset*) ;; (1 2 3)
(terpri) ;; prints a new line


Lisp
;; Checking Membership in a Set
  
(write (member 0 (list 1 2 3)))  ;; returns nil
(terpri) ;; prints a new line
  
(write (member-if #'evenp '(5 7 9 8 4 ) ));; returns t
(terpri) ;; prints a new line
  
(write (member-if-not  #'numberp '(3 7 2 5/3 'not 'number ))) ;; returns nil


Lisp
;; Set union in Lisp
  
  
(setq set1 (union '(1 2 3) '(2 3 4))) ;; set1 is (1 2 3 4)
(terpri) ;; prints a new line
  
(setq set2 (union '(a b 5 6 7 f h) '(5 6 7 a b g h)))
  
(write set1) ;; (1 2 3 4)
(terpri)
(write set2) ;; (F 5 6 7 A B G H)
(terpri)


Lisp
;; Set intersection in Lisp
  
  
(setq set1 (intersection '(1 2 3) '(2 3 4))) ;; set1 is (2 3)
(terpri) ;; prints a new line
  
(setq set2 (intersection '(a b 5 6 7 f h) '(5 6 7 a b g h))) 
  
(write set1) ;; (2 3)
(terpri) ;; prints a new line
   
( write set2) ;; (A B 5 6 7 H)
(terpri)  ;; prints a new line


Lisp
;; Set Difference in Lisp
  
  
(write(setq lst1 (list "A" "b" "C" "d") lst2 (list "a" "B" "C" "d"))) 
;; lst1 is ("A" "b" "C" "d") lst2 is ("a" "b" "C" "d")
(write(set-difference lst1 lst2)) ;; returns ("A" "C")
(terpri) ;; prints a new line
  
(write(set-difference lst1 lst2 :test 'equal)) ;; returns ("A" "C")
(terpri) ;; prints a new line
  
(write(nset-difference lst1 lst2 :test #'string=));; returns ("A" "b" "C" "d")
(terpri) ;; prints a new line


输出:

设置实施

检查集合中的成员资格:

Membership 是一个检查一个项目是否存在于集合中的函数。隶属函数定义如下:

这些函数探测项目的列表。如果该项目存在于列表中,则隶属函数返回 t。如果该项目不在列表中,则隶属函数返回 nil。搜索仅在顶层完成。搜索按列表顺序进行。

句法:

member item list test &key key &key => tail or nil

这里的item是要查找的item,list是要查找的list,test是要比较的item, &key是函数键。 Key 是用于在测试前提取值的函数。成员函数在列表中搜索项目。如果该项目存在于列表中,则隶属函数返回 t。如果该项目不在列表中,则隶属函数返回 nil。搜索仅在顶层完成。搜索按列表顺序进行。

例子:

创建一个新的lisp 文件并将其保存为membership.lisp。

语言

;; Checking Membership in a Set
  
(write (member 0 (list 1 2 3)))  ;; returns nil
(terpri) ;; prints a new line
  
(write (member-if #'evenp '(5 7 9 8 4 ) ));; returns t
(terpri) ;; prints a new line
  
(write (member-if-not  #'numberp '(3 7 2 5/3 'not 'number ))) ;; returns nil

输出:

集合中的成员资格

在 Lisp 中设置联合:

并集表示列表中所有项目的集合。使用并集函数,我们可以找到两个集合的并集。联合函数定义如下:

句法:

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

在这里,union函数接受两个列表 list1 和 list2,并返回一个新列表,其中包含两个列表中的所有项目。新列表中不允许有重复项。

例子:

创建一个新的 lisp 文件并将其保存为union.lisp。

语言

;; Set union in Lisp
  
  
(setq set1 (union '(1 2 3) '(2 3 4))) ;; set1 is (1 2 3 4)
(terpri) ;; prints a new line
  
(setq set2 (union '(a b 5 6 7 f h) '(5 6 7 a b g h)))
  
(write set1) ;; (1 2 3 4)
(terpri)
(write set2) ;; (F 5 6 7 A B G H)
(terpri)

输出:

集合中的并集

在 Lisp 中设置交集:

交集可以认为是两个集合共有的项目集合。要进行交集,我们可以使用交集函数组。它需要两个列表并返回一个新列表,其中包含两个列表共有的所有项目。交集函数定义如下:

句法:

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

这里的交集函数接受两个列表,list1 和 list2,并返回一个新列表,其中包含两个列表共有的所有项目。交集与交集函数相同,只是它使用其单元格破坏 list1 以构造结果 list2 并返回结果 list2。

例子:

创建一个新的 lisp 文件并将其保存为intersection.lisp。

语言

;; Set intersection in Lisp
  
  
(setq set1 (intersection '(1 2 3) '(2 3 4))) ;; set1 is (2 3)
(terpri) ;; prints a new line
  
(setq set2 (intersection '(a b 5 6 7 f h) '(5 6 7 a b g h))) 
  
(write set1) ;; (2 3)
(terpri) ;; prints a new line
   
( write set2) ;; (A B 5 6 7 H)
(terpri)  ;; prints a new line

输出:

Lisp 中的集合交集

在 Lisp 中设置差异:

集合差异是在第一个集合中但不在第二个集合中的项目集合。使用集差函数,我们可以找到两个集合的集差。集合差分函数定义如下:

句法:

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

在这里,设置差异函数接受两个列表,list1 和 list2,并返回一个新列表,其中包含第一个列表中但第二个列表中没有的所有项目。 nset-difference 与 set Difference函数相同,只是它使用其单元格破坏 list1 以构造结果 list2 并返回结果 list2。

Set-difference 返回第一个列表中但不在第二个列表中的项目列表。

Nset是 set-difference 的破坏性版本,它破坏 list1 并返回结果 list2。

例子:

创建一个新的 lisp 文件并将其保存为set-difference.lisp。

语言

;; Set Difference in Lisp
  
  
(write(setq lst1 (list "A" "b" "C" "d") lst2 (list "a" "B" "C" "d"))) 
;; lst1 is ("A" "b" "C" "d") lst2 is ("a" "b" "C" "d")
(write(set-difference lst1 lst2)) ;; returns ("A" "C")
(terpri) ;; prints a new line
  
(write(set-difference lst1 lst2 :test 'equal)) ;; returns ("A" "C")
(terpri) ;; prints a new line
  
(write(nset-difference lst1 lst2 :test #'string=));; returns ("A" "b" "C" "d")
(terpri) ;; prints a new line

输出:

在 lisp 中设置差异