2013-10-08 64 views
0

我需要一个过程,它需要一个列表并检查一个元素是否是该列表的一部分,即使该列表包含列表。到目前为止,我已经写了这一点:在列表中找到列表中的元素

(define (element-of-set? element set) 
    (cond ((null? set) #f) 
    ((eq? element (car set)) #t) 
    (else (element-of-set? element (cdr set)))))) 

但是,如果你有一个看起来像这样的列表:

​​

然后我写element-of-set?不承认3是这份名单的一部分。我究竟做错了什么?

回答

0

您没有重复发表您的set论点的car

如果你当前的element-of-set?定义评估

(element-of-set? 3 '(a (a b b (c b) 3) 5 5 (e s) (s e s))) 

,它会如果(eq? 3 'a)做类似

  • 检查了,没了。
  • 检查是否(eq? 3 '(a b b (c b) 3)),不。
  • 检查,如果(eq? 3 5),没了
  • 检查,如果(eq? 3 5),没了
  • 检查,如果(eq? 3 '(e s))了,没
  • 检查,如果(eq? 3 '(s e s)),都能跟得上。
  • 我不在列表中; 3不是'(a (a b b (c b) 3) 5 5 (e s) (s e s))

如果你想检查深集合成员的一员,你需要重新定义你的程序,使其复发成setcar如果该元素本身就是一个list。像

... 
((list? (car set)) (or (element-of-set? element (car set)) 
         (element-of-set? element (cdr set)))) 
... 

事情应该做,假设list?实际上是定义(我没有这台机器上的方案解释,所以我不知道。你可能需要使用(not (atom? (car set)))代替)。

0

而不是根据列表列表来思考,这可能是一个有用的地方,从根据对(也称为cons单元)构建的树来思考。当你打电话给(cons x y时,你会收到一个反馈小组),x被称为car,而y被称为cdr。当你在某个对象object搜索元素e,你可以这样来做:

  1. e一样object?如果是这样,你找到了!
  2. (a)object是一对吗?如果是这样,那么检查e是(b)在其car还是(c)在cdr,如果是的话,那么你已经找到它了!
  3. 否则,你还没有找到它,它无处可寻。

这是比较直接翻译成代码,您甚至可以使用orand让它非常干净:

(define (tree-find e object) 
    (or (eq? e object)       ; 1. 
     (and (pair? object)      ; 2.a 
      (or (tree-find e (car object))  ; 2.b 
       (tree-find e (cdr object)))))) ; 2.c 

现在,这甚至可以让你的树中找到一棵树的子部分。例如,如果你拿着树'((1 2) (3 (4 5)) (6 7))并提取其第二个元素(列表(3 (4 5))),并询问它是否是其成员,你会得到肯定的答案。需要注意的是这个作品,因为你与eq?检查,所以它只会发现相同对象,不只是一个具有相同的结构:

(let* ((l '((1 2) (3 (4 5)) (6 7))) 
     (e1 (cadr l))   ; (3 (4 5)), from l 
     (e2 (list 3 '(4 5)))) ; (3 (4 5)), but not from l 
    (display (tree-find e1 l)) ; #t 
    (display (tree-find e2 l))) ; #f 

但是,因为适当的名单是由一个空表终止(例如,(1 2 3)(1 . (2 . (3 .())))),tree-find将总是说'()是一个成员,如果输入中有适当的列表。因此,你可能想明确禁止这种情况:

(define (tree-find e object) 
    (or (and (eq? e object) 
      (not (null? e)))     ; check only non-null objects 
     (and (pair? object) 
      (or (tree-find e (car object)) 
       (tree-find e (cdr object)))))) 
0

你只需要一个条款来检查car是一个列表。添加到您的cond(在eq?语句之后):

((list? (car set)) 
(or (element-of-set? element (car set)) 
    (element-of-set? element (cdr set)))) 

这递归任何子列表。