Scheme - 如何返回INFINITE数量的集合的交集?

时间:2016-11-09 14:33:31

标签: set scheme intersection infinite

我正在尝试编写一个适用于无限量集的函数,而不仅仅是只需要两个集的普通交集函数。然而,我写了一个正常的交集函数(只需要2组),如下所示:

(define intersection
 (lambda (s1 s2 [res '()])
  (cond ((set-empty? s1) (make-set res))
        ((member? (set-first s1) s2) (intersection (set-rest s1) s2 (set-insert (set-first s1) res)))
        (else (intersection (set-rest s1) s2 res)))))

我有一个断开的交集函数,它试图将无限量的集合作为参数调用" intersection *"。它目前看起来像这样:

(define intersection*
 (lambda (s1 s2 . r)
  (cond ((set-empty? r) (intersection s1 s2))
        (else (intersection s1 (apply append s2 r))))))

论点' r'是一个休息的论点。

但是我确实设法编写了一个需要无限量集的Union函数:

(define union*
 (lambda (s1 [s2 '()] . r)
  (cond ((set-empty? r) (union s1 s2))
        (else (union s1 (apply append s2 r))))))

您可能会注意到union *函数和intersection *函数看起来几乎相同。那是因为我试图在union *函数中拼命使用与union *函数相同的逻辑。我也没想到它会起作用......我的想法已经不多了。有帮助吗?

1 个答案:

答案 0 :(得分:2)

只要intersection被正确实现,你只需要将前两个集合相交,然后将结果与下一个集合相交,然后是下一个,依此类推。这应该有效:

(define (intersect* s1 s2 . r)
  (foldl intersect (intersect s1 s2) r))

以上内容与:

相同
(define (intersect* s1 s2 . r)
  (let helper ((acc (intersect s1 s2)) (r r))
    (if (null? r)
        acc
        (helper (intersect (first r) acc) (rest r)))))

奖励:此版本短路,一旦找到空交叉点,就会返回:

(define (intersect* s1 s2 . r)
  (let helper ((acc (intersect s1 s2)) (r r))
    (cond ((null? r) acc)
          ((null? acc) '())
          (else (helper (intersect (first r) acc) (rest r))))))