List LISP:如何测试两个列表是否具有相同的元素?
我想编写一个函数,将两个列表作为参数,并检查第一个列表中的每个元素是否都包含在第二个列表中(元素的顺序无关紧要)。函数还将检查两个列表是否具有相同的长度(两个列表不能有重复的元素),因为如果没有,则函数将返回nill/false 例如: (A B C D E F)和(B E A F D C)具有相同的元素 (nil)和(nil)具有相同的元素 (abcdef)和(abcdefg)没有相同的元素 问题是我只知道一些基本的命令,我只能使用这些命令。这些几乎是我所知道的所有命令:List LISP:如何测试两个列表是否具有相同的元素?,list,lisp,equality,List,Lisp,Equality,我想编写一个函数,将两个列表作为参数,并检查第一个列表中的每个元素是否都包含在第二个列表中(元素的顺序无关紧要)。函数还将检查两个列表是否具有相同的长度(两个列表不能有重复的元素),因为如果没有,则函数将返回nill/false 例如: (A B C D E F)和(B E A F D C)具有相同的元素 (nil)和(nil)具有相同的元素 (abcdef)和(abcdefg)没有相同的元素 问题是我只知道一些基本的命令,我只能使用这些命令。这些几乎是我所知道的所有命令: CAR, CDR,
CAR, CDR, LENGTH, NULL, MEMBER, NOT, AND, OR, NOT, MAPCAR, APPLY, DO, SETQ, LET
到目前为止,我编写了以下函数,但我不知道如何检查重复的成员,并且对于我要检查的所有列表,它都不能正常工作:
(defun same-elem-p (lst1 lst2)
(cond ((not (null lst1))
(cond ((member (car lst1) lst2)
(same-elem-p (cdr lst1) lst2))
(t nil)))
(t t)))
我希望我对这个问题解释得足够好。编写一个函数,该函数映射到列表1以及列表1中的每个元素
您可以定义一个函数,该函数在列表包含另一个时返回true:
(defun member (x liste)
(cond
((null liste) ())
((equal (car liste) x) liste)
(t (member x (cdr liste)))))
(defun inclus (liste1 liste2)
(cond
((null liste1) t)
((member (car liste1) liste2)(inclus (cdr liste1) liste2))
(t ())))
然后使用它来确定两个列表是否相等:
(defun compare (liste1 liste2)
(if ((and (inclus liste1 liste2) (inclus liste2 liste1)))
(print "the 2 lists are equivalent")
(print "the 2 lists aren't equivalent")))
如果您的元素是数字,或者如果您有一个合适的元素比较器(在本例中是字母顺序),您可以简单地对两个列表使用“排序”过程,然后检查它们是否相同
从理论上讲,整个操作的复杂性大约为O(N log(N))(因为'sort'的Lisp实现非常好)。至于Hedi的答案,其复杂度将类似于O(N²/2)(因为“成员”将被调用N次,每次调用的平均时间为(N/2))。将列表视为一个集合,如果您可以使用更多命令,如:
INTERSECTION SET-DIFFERENCE EQ
您可以定义此函数:
(defun equal-lists (list1 list2)
(and (eq (null (intersection list1 list2)) nil)
(null (set-difference list1 list2))))
然后,如果交叉点不是空集合,且差异为空,则set1等于set2。当一个列表中的每个元素都是另一个列表的成员时,两个列表具有相同的元素,反之亦然。假设您可以使用
每个
功能,下面是一种快速测试方法:
(defun same-elements (lst1 lst2)
(and (= (length lst1) (length lst2))
(every #'(lambda (x) (member x lst2))
lst1)
(every #'(lambda (x) (member x lst1))
lst2)))
例如:
CL-USER> (same-elements '(a b c) '(c a b))
T
请注意,此代码不会处理所有情况。例如,当两个列表中重复两个不同的元素时,它将返回
T
,如(a b c)
和(a b c)
。但是,在大多数情况下,它完成了它的工作。两个列表包含相同的元素,如果它们是彼此的子集
(defun same ( a b )
`(cond
(( null a )'same )
((member(car a ) b ) (same(cdr a ) b ))
(t'nosame )))
(defun entre ( )
(let(( a ) ( b ))
(princ " list a : " ) (setq a (read ))
(princ " list b : " ) (setq b (read ))
(if (= (length a ) (length b )) (same a b ) 'nosame )))
(defun same-elements (l1 l2)
(and (subsetp l1 l2) (subsetp l2 l1)))
谢谢你的回答。是否可以在一个函数中编写所有这些内容?我想知道你为什么写成员函数;它在LISP中还不存在?当然有办法,但我不认为它会很简单!是的,成员函数已经存在,但我忘记了。我已经一年多没有用LISP编程了。请用更多信息编辑。不鼓励只编写代码和“试试这个”答案,因为它们不包含可搜索的内容,也不解释为什么有人应该“试试这个”。