2013-10-26 39 views
3

可以说我有两个列表,((1 2 3))(((1 2 3)) ((4 5)))。我想知道第一个列表是否是第二个列表的成员。我试图使用subsetp,但对于此查询它不返回true。我怎样才能做到这一点?如何测试一个列表是否是另一个列表的

+1

第一个列表如何将是第二列表的子集? ?? –

+0

因为第二个列表的第一个元素等于第一个列表。 –

+3

这不是一个子集。这是*会员*。第一个列表是第二个列表的成员,但不是子集。 –

回答

3

如果要将列表作为subsetp的设置元素,则必须更改:test关键字的值。

CL-USER 1 > (subsetp '(1 2 3) '(1 2 3 4 5)) 
T 
CL-USER 2 > (subsetp '((1) (2) (3)) '((1) (2) (3) (4) (5))) 
NIL 

第一个给出T,第二个给出NIL。为什么?因为平等与#'eql检查,它适用于相同的对象或相同的值和相同类型的数字。由于两个列表不能是相同的对象,因此(eql '(1) '(1))会给出NIL。 (这可能取决于你的CL实现。)如果你想比较一个conses树,tree-equal可以帮助你。

CL-USER 3 > (subsetp '((1) (2) (3)) '((1) (2) (3) (4) (5)) :test #'tree-equal) 
T 

我完全不理解你给出的例子的结构,但我希望这有助于。

+0

不幸的是,它不适用于我的列表结构 –

4

由于Rainer Joswig mentioned in the comments,您并未检查子集,但是对于成员,您可以使用恰当名称的member函数进行检查。 Member返回一个广义布尔值,即nil为false,而某些事物,不一定为t,非nil为真。具体而言,如果元素是列表的成员,则member返回列表的尾部,其第一个元素是元素。

CL-USER> (member 3 '(1 2 3 4 5)) 
(3 4 5) 
CL-USER> (member 7 '(1 2 3 4 5)) 
NIL 

当然,当检查列表中的成员资格时,存在如何将给定项目与列表元素进行比较的问题。 Member的默认比较是eql,它处理数字等事情,如上例所示。对于你的情况,但是,你可能想用equal测试,因为((1 2 3))可能不是相同对象为(((1 2 3)) ((4 5)))第一个元素:

CL-USER> (member '((1 2 3)) '(((1 2 3)) ((4 5)))) 
NIL 
CL-USER> (member '((1 2 3)) '(((1 2 3)) ((4 5))) :test 'equal) 
(((1 2 3)) ((4 5))) 
CL-USER> (member '((4 5)) '(((1 2 3)) ((4 5))) :test 'equal) 
(((4 5))) 
CL-USER> (member '((1 2 4)) '(((1 2 3)) ((4 5))) :test 'equal) 
NIL 
相关问题