回答:
各セットは他のセットが存在するかの記録を維持し、あなたが全体の持っている場合はセット、簡単に(収集のために任意のデータ構造を変えることができます例えば、二分探索木をなど、あなたがの検索を持つことができるものに)時間O (log s )の2セットの交点の要素。
各セットには、完全に順序付けられたセットの一意の識別子が必要です。セットに明示的に名前を付けると、識別子は単なるインデックスになります。
セットの「レジストリ」を実装する必要があります。定義したすべてのセットのコレクションを保持するデータ構造。レジストリは、検索ツリーデータ構造として実装する必要があります。これにより、検索を簡単に(たとえば 、セットを削除する場合)、セットの線形時間走査が可能になります。
各セットは、他の各セットの「インデックス」も保持します。それらのコピーではなく、他のセットのラベルによってインデックス付けされたデータ構造です。このインデックスは、各セットのために、維持するために使用されるS k個の要素のすべてのバイナリ検索ツリーSのJ ∩ S K。(2つのセットS jとS kは、その検索ツリーの1つのコピーを共有します。)
初期化
セットの初期から成るO (1 )操作はその要素のツリー初期化するO (S )あなたは(レジストリからのコピー)を初期化などの操作を設定するための指標T、およびO (S ログS )レジストリを走査してTを他の各セットS jのインデックスに追加するときの操作。指標ではT、我々は代表探索木作成T ∩ Sのjは = ∅他のセット。S jのインデックスに同じポインタをコピーします。
セットTへの要素の追加
いくつかの追加セットにTが時間かかりO (ログN Tの)ここで、いつものように、N T = | T | 。我々のメンバーシップのために、試験のx他のセットの各々におけるS 1、S 2、...時間かかり、O (ログN S 1 + ログN S 2 + ⋯ )⊆ O (S ログNをここで n = | V | はユニバース(または最大セット S j)のサイズであり、 sはレジストリ内のセットの数です。各セットのために S jのような xは∈ Sのjは、インサート、 Xセットのインデックスに S J ∩ T。このような各セットについて S jを、これがかかり O (ログS +のログN T)ルックアップする時間を、 S jは
交差点試験
エレメント除去
セット削除
備考
一定数のセットのみを実装する場合、上記の実行時間は次のように短縮されます。
最悪の場合でも、線形時間未満でこれを行うことができるデータ構造があります。http://research.microsoft.com/pubs/173795/vldb11intersection.pdf(およびそこにある論文参照)を参照してください。
2つのセットSとTの交差部分が大きく、Sの辞書がある場合、Tの要素をランダムな順序で検索すると、すぐに共通の要素が得られます。最も難しいケースは、交差サイズが0または1の場合です。
通常、選択したプログラミング言語は、一意の要素を持つデータ構造をサポートします。一般に、ツリー、ハッシュ、ビットマスクという3つの一般的なアプローチがあります。ツリー要素は比較可能でなければならず、ハッシュ要素はハッシュ可能でなければならず、ビットマスク要素は整数への何らかの変換方法を持たなければなりません。
ツリーセットは、O(log n)への挿入と、最悪の場合のO(n log n)での交差テストをサポートします。
ハッシュセットは、「h」がハッシュアルゴリズムの実行時間であるAmortized O(1 * h)への挿入と、最悪の場合のO(n)での交差テストをサポートします。
通常、ビットマスクセットは、ツリーセットやハッシュセットのようには使用されません。
あなたのケースが偽陽性の回答を許可する場合、私は単一のハッシュ関数でブルームフィルターを使用します。
次のように実装できます。
空のセットを初期化する
セットに要素を追加します。
2つのセット(B1、B2)が与えられた場合、それらが交差するかどうかを報告します。
複雑