我对此功能two-similar-p
有疑问。
(defun two-similar-p (list1 list2)
(mapcar
(lambda (e)
(mapcar
(lambda (e1)
(if (equal e e1) t))
list2))
list1))
但是使用mapcar
是不正确的,因为此函数返回一个包含T
或NIL
的新列表,但我只需要返回true或false。
离。
(two-similar-p '(2 1 3) '(1 2 3))
==> ((NIL T NIL) (T NIL NIL) (NIL NIL T))
我正在考虑使用递归来比较各种元素,但我不知道如何做到这一点。 我的功能需要像:
(two-similar-p '(1 2 3) '(1 4 5)) ; ==> nil
(two-similar-p '(1 2 5) '(1 4 5)) ; ==> t
(two-similar-p '(1 2 6) '(6 4 2)) ; ==> t
有什么建议吗?
答案 0 :(得分:1)
最简单的“现成”解决方案是检查intersection
是否包含至少两个元素:
(defun two-similar-p (l1 l2)
(consp (cdr (intersection l1 l2 :test #'equal))))
稍微少一点的OTS解决方案是使用hash tables:
(defun two-similar-p (l1 l2)
(let ((h1 (make-hash-table :test 'equal))
(common 0))
(dolist (x l1)
(setf (gethash x h1) t))
(dolist (x l2)
(when (gethash x h1)
(incf common))
(when (>= common 2)
(return t)))))
第二种方法的优点是其复杂性为O(len(l1) + len(l2))
,
而mapcar
方法将为O(len(l1) * len(l2))
。
标准没有指定intersection
和friends的复杂性,但大多数实现都在这里照顾好用户(IOW,复杂性将是线性的,而不是二次的)。