2012-03-30 3 views
1

私はすでにソートされている整数(つまり1,1,3,3,3,3,7,7、...)を保持する直接バッファを持っています。ほとんどの値は複数回発生します。私が検索する価値の最初の位置を見つけたい。ソートされた巨大なダイレクトバッファをJavaで効率的に検索するにはどうすればよいですか?

  1. バッファに直接作用する検索機能はありますか Javaに組み込まれていますか? (何も見つかりませんでした)
  2. もしそうでなければ、そのような機能を提供するまともなライブラリがありますか?そうでない場合
  3. 、実装のために推薦するものを検索アルゴリズム、ことを考える:

    • 私は通常私のバッファに数百万のエントリを持つことになります
    • 速度は、それが返さなければなりません
    • 非常に重要です検索された番号が最初に出現する
    • 後で元のデータが必要になるため、データを変更しないでください。

EDIT:Arrays.binarySearch()を示唆全てのポスターのおかげで、しかしが、私の知る限り、直接バッファは、一般的に補助配列を持っていません。そのため、私はバッファで直接動作する実装を探していました。

また、各値は1000回まで発生する可能性があるため、着陸点を見つけた後の線形探索はそれほど効率的ではないかもしれません。 dasblinkenlightのコンパレータ提案はうまくいくかもしれません。

+2

'Arrays.binarySearch'はトリックですか?何百万というエントリでは、30ステップ以下で答えを得られるはずです。最後の位置ではなく最初の位置を取得するためにカスタムコンパレータを用意する必要があるかもしれません。 – dasblinkenlight

+2

私はバイナリ検索を使用して番号を見つけ、その番号の最初の出現を得るまで左へ直線検索を開始します。 –

+0

@dasblinkenlight binarySearchの使用のみが動作しません。ここでは数字が重複しており、質問者は数字の最初の出現を望んでいるからです。 –

答えて

3

最善のアプローチは、バッファにBinary Searchの独自の実装をコーディングすることです。このアプローチは、ビューの作成、大規模な配列のコピーなどに伴う潜在的なパフォーマンスのヒットを慎重に避け、同時にコンパクトなままです。

リンクのコードサンプルは右端の点を返します。一番左の点を取得するには>nums[guess] > check行の>=に置き換える必要があります。これにより、潜在的に高価な後方線形検索が不要になります。Comparatorを使用すると、intIntegerオブジェクトにラップする必要があります。

+0

ありがとうございます。これが既に実装されているライブラリがない場合、それは私がやることです。 –

+0

@SeNorm既に実装されているライブラリがいくつかありますが、それを 'Buffer'に適合させるために少し微調整すれば、パフォーマンスが大幅に低下する可能性があります。実装にはわずか12行しかないので、「カスタム化」して大きなコストを節約するコストはほぼゼロです。 – dasblinkenlight

+0

そして、あなたが質問で言ったようにパフォーマンスが本当に重要であるなら、それは「ホイールを再発明する」ための十分な正当性です。 – biziclop

0

私はバッファの組み込み機能についてはわかりません(Arrays.binarySearch(...)はバッファを配列に変換する必要があります)が、バッファはすでにソートされているためバイナリ検索が便利かもしれません。値を見つけたら、以前の値をチェックしてそのシーケンスの開始点を得ることができます。バイト配列は、配列の使用をintに変換できる場合

2

使用Binary search algorithm

ByteBuffer buffer = createByteBuffer(); 
IntBuffer intBuffer = buffer.asIntBuffer(); 

int [] array = intBuffer.array(); 
int index = java.util.Arrays.binarySearch(array,7); 
+2

'intBuffer.array()'はオプションの操作です。 – dasblinkenlight

+1

これは、バイナリサーチが最初の要素を返すことを保証しないので、シーケンスの開始を得るために追加の逆方向リニアサーチを必要とします。 – Thomas

+0

java.util.Arrays.binarySearchを参照してください。 array [i]をintBuffer.get(i)に置き換えてください。 –

0

おそらく、自分のバイナリ検索を書く必要があります:チェックされた値と検索された値が等しい場合は、常に左に移動します。

xの代わりに効果的にx-εを検索します。アルゴリズムは常にlogn(またはlogn + 1)ステップを踏みますが、これは常に「失敗」しますが、x-εより大きい最初の要素のインデックスが与えられます。あなたがする必要があるのは、その要素がxであるかどうかを確認することだけです。そうであれば、一致するものを見つけました。そうでない場合は、バッファにxがありません。

関連する問題