ID|VALUE
1回のパスのように行を持つ大きなファイルがあります。
ID の繰り返しの場合、行は無視する必要があります。
このチェックを効果的に行う方法は?
追加: ID が長い (8 バイト)。最小限のメモリを使用するソリューションが必要です。
みんな助けてくれてありがとう。ヒープスペースを増やして Set を使用できるようになりました。
ID|VALUE
1回のパスのように行を持つ大きなファイルがあります。
ID の繰り返しの場合、行は無視する必要があります。
このチェックを効果的に行う方法は?
追加: ID が長い (8 バイト)。最小限のメモリを使用するソリューションが必要です。
みんな助けてくれてありがとう。ヒープスペースを増やして Set を使用できるようになりました。
データを TLongObjectHashMap に格納するか、TLongHashSet を使用できます。これらのクラスは、プリミティブ ベースの情報を効率的に格納します。
500 万の長い値は TLongHashSet で 60 MB 未満を使用しますが、TLongObjectHashMap も値を効率的に格納します。
これらのクラスについて詳しく知るには
基本的な解決策は 2 つあります。
まず、上記の duffymo と Andreas_D で提案されているように、すべての値を a に格納できますSet
。これにより、O(n) 時間の複雑さと O(n) のメモリ使用量が得られます。
次に、O(n) メモリが多すぎる場合は、速度を犠牲にして O(1) メモリで実行できます。ファイルの各行について、その前の他のすべての行を読み取り、ID が現在の行の前にある場合は破棄します。
重複を検出するには、とにかく ID をどこかに保存する必要があります。ここでは aHashSet<String>
とそのcontains
メソッドを使用します。
一度に 1 行ずつ、ファイル全体を読み取る必要があります。ID のセットを保持し、受信した ID をセット内の既存の値と比較する必要があります。値が表示された場合は、その行をスキップします。
ユースケースは自分で書きました。ここには魔法はありません。
これは、典型的なデータベース タスクのように思えます。アプリでデータベースを使用している場合は、それを利用してタスクを実行できます。UNIQUE INTEGER フィールドを持つテーブルを作成し、行の追加を開始します。重複した ID で例外が発生します。データベース エンジンがカーソルのウィンドウ処理とキャッシュを処理するため、メモリ バジェットに収まります。完了したら、そのテーブルをドロップします。
確率的アルゴリズムはどうですか?
ブルーム フィルター ... は、要素がセットのメンバーであるかどうかをテストするために使用される、スペース効率の高い確率的データ構造です。偽陽性は可能ですが、偽陰性はそうではありません。