512 個のファイルを簡単に開いたままにしておくことができるため、両方のセットをディスク上の 256 個のチャンク (最大 16M アイテム、サイズはそれぞれ 64 メガバイト) にプレブラウズできます。これは、set.A.00 から set.B.ff までの各 Long の最上位バイトに基づいて実行できます。
次に、対応するチャンクの各ペア ( にset.A.42
対応する 0x42 で始まる Long を含むset.B.42
) をロードし、それらを使用して 16M バイト配列を初期化します。すべて 0 に初期化しi
、最初のチャンクから値を読み取るときに、インデックス i をインクリメントします。 -th)。次に、2 番目のチャンクを読み込みますが、今回は 2 ずつインクリメントします。
完了したら、アレイのスキャンを実行します。0 は値がどちらのチャンクにも存在しないことを意味し、1 は最初のセットにのみ存在することを意味し、2 は 2 番目のセットにのみ存在し、3 は両方に存在することを意味します。そして、結果を結果ファイルに書き込みます。
結果ファイルがソートされる場合でも、ソートする必要はありません (チャンクを順番にチェックし、順番に最終スキャンを実行するため)。
これはすべて O(n) で実行され (すべてのステップは線形時間で実行されます)、最大で 16M の RAM が必要です。
512 個の開いているファイルが多すぎる場合は、最初の 7 つの最上位ビットを使用して、256 個の開いているファイルと 32M の RAM を使用できます。または、128 個の開いているファイルと 64M の RAM など。
また、それぞれのサイズが 16384 の一連の 256 個の「バケット」を保持することもできます (ファイルシステムのキャッシュがあまり良くない場合は、おそらくより効率的です) Longs
(したがって、これも 16M になります)。バケットがいっぱいに近づくと、ディスク上の対応するチャンク ファイルを開き、Long
これまでに見つかった 16384 をダンプして、ファイルを閉じます。Long
次に、セット B についても同じことを行います。一度に 2 つ以上のファイルを開いたままにしておくと、0 (可能性は低い) から 1600 万の s を含む 512 個のファイルができあがります。