LISP:如何测试两个列表是否具有相同的元素?

时间:2013-04-02 09:46:18

标签: list lisp equality

我想编写一个函数,它将参数作为参数两个列表,并检查第一个元素中的每个元素是否包含在第二个元素中(元素的顺序无关紧要)。该函数还将检查两个列表是否具有相同的长度(两个列表不能有重复的元素),因为如果没有,那么该函数将返回nill / false。

例如: (A B C D E F)和(B E A F D C)具有相同的元素 (nil)和(nil)具有相同的元素

(A B C D E F)和(A B C D E F G)没有相同的元素

问题是我只知道一些基本命令,我只能使用那些命令。这几乎是我所知道的所有命令:

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))) 

我希望我能够很好地解释这个问题。

7 个答案:

答案 0 :(得分:6)

您可以定义一个函数,当列表包含另一个列表时,该函数返回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"))) 

答案 1 :(得分:3)

当一个列表中的每个元素都是另一个列表的成员时,两个列表具有相同的元素,反之亦然。假设您可以使用every函数,快速测试方法如下:

(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 b c)(a a b c)。但是,在大多数情况下,它确实起到了作用。

答案 2 :(得分:2)

编写一个映射到list1和list1

中每个元素的函数
  1. 在list2中找到它。如果它不在list2中,则失败。
  2. 否则将其从list2中删除

答案 3 :(得分:0)

如果你的元素是数字,或者你有一个合适的元素比较器(在这种情况下是按字母顺序排列),你可以简单地对两个列表使用'sort'程序,然后检查它们是否相同。

从理论上讲,整个操作的复杂性大约为O(N log(N))(因为'sort'的Lisp实现非常好)。至于Hedi的答案,复杂性就像O(N²/ 2)(因为'成员'将被称为N次,每次调用的平均时间为(N / 2))。

答案 4 :(得分:0)

将列表作为集合处理,以及是否可以使用更多命令,如:

INTERSECTION SET-DIFFERENCE EQ

您可以定义此功能:

(defun equal-lists (list1 list2)
(and (eq (null (intersection list1 list2)) nil)
(null (set-difference list1 list2))))

如果交集不是空集,并且差异为空,则set1等于set2。

答案 5 :(得分:0)

(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 )))

答案 6 :(得分:0)

如果两个列表是彼此的子集,则它们包含相同的元素。

id's