我需要像这样 ,元素的集合不包含任何元素的副本。 是否Common Lisp的,特别是SBCL,有这样任何事物?
Answer 1:
对于一个快速的解决方案,只需使用哈希表,这在前面已经提到。
但是,如果你喜欢一个更原则的方法,你可以看看F若有 ,这是“功能性的集合论的集合库”。 其中,它包含组和袋类和操作。
(编辑:)最干净的方式很可能是来定义你面向集合的操作的通用功能。 一组通用的功能基本上等同于一个Java接口,毕竟。 你可以简单地实现对标准的哈希表类作为第一个原型方法,并允许其他实现也是如此。
Answer 2:
看看CL-容器 。 有一组容器类。
Answer 3:
你可以使用列表,虽然他们可以被证明是低效为代表的大集。 这是通过使用相邻或做PUSHNEW到一个新的元素添加到列表, 删除或移除反其道而行之。
(let ((set (list)))
(pushnew 11 set)
(pushnew 42 set)
(pushnew 11 set)
(print set) ; set={42,11}
(setq set (delete 42 set))
(print set)) ; set={11}
有一点需要注意的是所有这些运营商使用EQL默认以测试该组潜在的重复(就像Java使用equals方法)。 这对于持有套数字或字符,但是对于套其他对象的确定,一个'更深的”平等的测试,如平等 ,应指定为:TEST关键字参数,例如,对于一组字符串: -
(let ((set (list)))
(pushnew "foo" set :test #'equal)
(pushnew "bar" set :test #'equal)
(pushnew "foo" set :test #'equal) ; EQUAL decides that "foo"="foo"
(print set)) ; set={"bar","foo"}
Lisp的同行一些Java的一组操作是:
- 的addAll - > UNION或NUNION
- containsAll - > SUBSETP
- 的removeAll - > SET-差或NSET差
- 的retainAll - > 交会或NINTERSECTION
Answer 4:
是的,它有套。 见的“设置”这一部分 ,从实用的Common Lisp。
基本上,你可以创建一组与pushnew
和adjoin
,与查询其member
, member-if
和member-if-not
,跟其他台具有类似功能结合起来intersection
, union
, set-difference
, set-exclusive-or
和subsetp
。
Answer 5:
容易解决使用哈希表。
(let ((h (make-hash-table :test 'equalp))) ; if you're storing symbols
(loop for i from 0 upto 20
do (setf (gethash i h) (format nil "Value ~A" i)))
(loop for i from 10 upto 30
do (setf (gethash i h) (format nil "~A eulaV" i)))
(loop for k being the hash-keys of h using (hash-value v)
do (format t "~A => ~A~%" k v)))
输出
0 => Value 0
1 => Value 1
...
9 => Value 9
10 => 10 eulaV
11 => 11 eulaV
...
29 => 29 eulaV
30 => 30 eulaV
Answer 6:
这并不是说我知道的,但您可以使用杂凑表相当类似的东西。
Answer 7:
Lisp的哈希表是基于CLOS。 规格在这里 。
Answer 8:
就个人而言,我只想实现一个函数,它接受一个列表,并返回了一套独特的。 我起草的东西在一起,其工作对我来说:
(defun make-set (list-in &optional (list-out '()))
(if (endp list-in)
(nreverse list-out)
(make-set
(cdr list-in)
(adjoin (car list-in) list-out :test 'equal))))
基本上, adjoin
功能前添加的项到列表非破坏性当且仅当该项目不已经存在于列表中,接受一个可选的测试功能(Common Lisp的“相等”功能中的一个)。 您还可以使用pushnew
这样做的破坏性,但我发现了尾递归执行是更为优雅。 所以,Lisp语言做出口的基本功能,使您可以使用列表作为一组; 没有需要的内置数据类型,因为你可以使用不同的功能进行预先考虑的事情的清单。
所有这一切我的数据源(不是功能,而是资讯)一直是组合的Common Lisp HyperSpec和Common Lisp的语言(第2版) 。