方案 - 如何 return 无限数量的集合的交集?

Scheme - How to return the intersection of an INFINITE amount of sets?

我正在尝试编写一个适用于无限数量集合的函数,而不仅仅是只需要两个集合的普通交集函数。然而,我写了一个普通的交集函数(只需要 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' 是剩余参数。

但是我确实设法编写了一个接受无限数量集合的联合函数:

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

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

只要正确实施 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)))))

奖励:此版本短路,一旦找到空路口,returns:

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