2016-11-09 7 views
1

私は、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))))) 

:しかし私は、このようになり、通常の交差点機能を(それが唯一の2セットを取る)書かれています。現在のところ、次のようになります。

(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関数で同じロジックを使用しようとしたためです。私はそれが働くことを期待していなかった...私はちょうどアイデアが不足しています。どんな助け?

+3

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

を上記と同じです恣意的に多くのものは、無限に多くのものと同じではありません。 – molbdnilo

+0

リストとして実装されたセットでappendを使用するとすぐに、その要素がセット内で1回だけ発生するというプロパティが破られる可能性があります。連合と交点が予想どおりに動作しない可能性があります。ここでは集合を追加していますが、これは組合のための作品の種類ですが、これは交差点には意味がありません。 – coredump

答えて

2

intersectionが正しく実装されている場合は、最初の2つのセットを一緒に交差させ、次にそのセットの結果と次のセットなどと交差させるだけです。これは動作するはずです:

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

これを短絡することはできません。例えば。 2番目の '' acc''は空のセットなので、結果があるので停止できますか? – Sylwester

+0

'fold'操作ではありません...リーダーの練習として残された継続的な解決策:P –

+0

しかし、あなた自身の' intersect * 'は簡単にそれを行うことができます。 – Sylwester

関連する問題