x-by-y の大きな 2D グリッドがあります。アプリケーションのユーザーは、このグリッド上の特定のポイントに関するデータを追加します。残念ながら、グリッドが実行されているシステムには十分なメモリがないため、グリッドは大きすぎて大きな x 行 y 列の配列として実装できません。
データが追加されたポイントのみがメモリに保存されるように、これを実装する良い方法は何ですか?
私の最初のアイデアは、データ ポイントの BST を作成することでした。ノードの比較には、「(long)x<<32 + y」などのハッシュ関数が使用されます。
次に、バランスが取れていないと効率が低下する可能性があると結論付けたので、ポイントの同等の BST の BST を使用するというアイデアを思いつきました。外側の BST は、x 値に基づいて内側の BST を比較します。内側の BST は、点を y 値で比較します (そして、それらはすべて同じ x になります)。そのため、プログラマーが (5,6) にポイントがあるかどうかを確認したい場合、外側の BST に 5 を問い合わせます。そのポイントに内側の BST が存在する場合、プログラマーは内側の BST に 6 を問い合わせます。結果は次のようになります。返されます。
これを実装するためのより良い方法を考えられますか?
編集: HashMaps に関して: ほとんどの HashMaps には、ルックアップ用の配列が必要です。「data[hash(Point)] = Point();」と言う人もいるでしょう。ポイントを設定し、それをハッシュしてインデックスを見つけることでポイントを見つけます。ただし、問題は、配列がハッシュ関数の範囲のサイズでなければならないことです。この範囲が追加されるデータ ポイントの総数よりも少ない場合は、余裕がないか、オーバーフローに追加する必要があります。追加されるポイントの数がわからないため、この数が特定の量よりも少ないと仮定して、配列をそのサイズに設定する必要があります。繰り返しますが、これは非常に大きな配列をインスタンス化します (ただし、x*y よりもデータ ポイントが少ないと仮定すると、元の配列よりも小さくなります)。
一部の人が言及したように、私が欲しいのはSparseArrayのようです。それらは、BST 内に BST を持つのと同様に実装されていますか?
Edit2: Map<> はインターフェースです。Map を使用する場合は、TreeMap<> が最適なようです。したがって、人々が行った Map< Map< Point> > の提案に似た TreeMap< TreeMap< Point> > になります。これは基本的に BST 内の BST です。TreeMap<> が基本的に BST の Java SDK であることを知らなかったので、情報をありがとう。
Edit3: 関係者にとっては、選択された回答が最善の方法です。最初に、(x,y) を含み、comparable を実装する Point クラスを作成する必要があります。Point は、(((long)x)<<32)+y) のようなもので比較できる可能性があります。次に、それぞれのデータを指す TreeMap を作成します。バランスの取れたツリーにあるため、これを検索すると効率的であり、log(n) のコストがかかります。ユーザーは、データとともに Point のセットを返す TreeMap.entrySet() 関数を使用して、このデータのすべてを照会したり、データを繰り返し処理したりすることもできます。
結論として、これにより、スパース配列 (私の場合は 2D 配列) のスペース効率と検索効率の高い実装が可能になり、効率的に反復することもできます。