为什么集合A和集合B的联合过程返回集A而没有其他?

问题描述 投票:1回答:2

我正在研究SICP练习2.59,它要求读者“实现集合的无序列表表示的联合集操作”。两组的并集 - 由A∪B表示 - 是A,B,或A和B中的元素集。

这是我为执行此操作而编写的代码:

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

(define (union a b)
  (cond ((null? a) b)
        ((null? b) a)
        (element-of-set? (car b) a)
          (union a (cdr b))
        (else (cons (car b) a))))

我在一组赔率和平均值(define odds '(1 3 5)) (define evens '(0 2 4 6)) (union odds evens)上测试了它,当预期输出为(1 3 5)时得到了(1 3 5 0 2 4 6)的输出。任何人都可以解释为什么我得到这个输出以及如何重写代码以获得预期的输出?

以下是工作联合过程的示例:

(define (union-set s1 s2) 
   (if (null? s1) 
     s2 
     (let 
       ((e (car s1))) 
       (union-set 
         (cdr s1) 
         (if (element-of-set? e s2) s2 (cons e s2)))))) 
set scheme lisp sicp
2个回答
2
投票

您的代码有两个问题:

  • 在第三种情况下,你忘记了几个()
  • 在最后一个条件中,我们还必须调用递归

这应该解决它:

(define (union a b)
  (cond ((null? a) b)
        ((null? b) a)
        ((element-of-set? (car b) a)
         (union a (cdr b)))
        (else (cons (car b) (union a (cdr b))))))

或者,如果要保留与问题的示例输出中完全相同的顺序:

(define (union a b)
  (cond ((null? a) b)
        ((null? b) a)
        ((not (element-of-set? (car a) b))
         (cons (car a) (union (cdr a) b)))
        (else (union (cdr a) b))))

2
投票

在你的else条款中,你不要打电话给union所以你在cdr b失去了一切。

也许:

(else (union (cons (car b) a) (cdr b)))
© www.soinside.com 2019 - 2024. All rights reserved.