Common Lisp 定义了许多将列表作为集合处理的函数,因此您无需编写自己的函数。特别是,有用的功能出现在The Conses Dictionary的底部。特别有用的是
subsetp
几乎可以满足您的要求,但它正在检查不正确的子集。但是,请注意您可以使用这些函数来计算您需要的内容。最直接的方法是检查A是否是B的子集,以及B - A ≠ {}是否。这符合您的描述,“a 的每个元素都在 b 中找到,b 有另一个元素”。
(defun proper-subsetp (a b)
(and (subsetp a b) ; every element of a is found in b
(not (endp (set-difference b a))))) ; b has another element
CL-USER> (proper-subsetp '(1 2 3) '(1 2 3 4))
T
CL-USER> (proper-subsetp '(1 2 3 4) '(1 2 3 4))
NIL
由于这些函数实际上采用了一些参数,这些参数可以让您确定如何比较元素。您可以使用&rest
参数添加这些并应用:
(defun proper-subsetp (a b &rest keys)
(and (apply 'subsetp a b keys )
(not (endp (apply 'set-difference b a keys)))))
使用它,您可以比较它们的长度,而不是直接比较元素:
CL-USER> (proper-subsetp '("a" "bb" "ccc") '("1" "22" "333") :key 'length)
NIL
CL-USER> (proper-subsetp '("a" "bb" "ccc") '("1" "22" "333" "4444") :key 'length)
T