整数の範囲を効率的に格納するデータ構造はどれですか。


10

コレクションを0から65535の範囲の整数で保持する必要があるため、次のことをすばやく実行できます。

  • 新しい整数を挿入する
  • 連続する整数の範囲を挿入する
  • 整数を削除する
  • 整数以下のすべての整数を削除します
  • 整数が存在するかどうかをテストします

私のデータには、コレクションに整数の実行が含まれることが多いという特性があります。たとえば、ある時点でのコレクションは次のようになります。

{ 121, 122, 123, 124, 3201, 3202, 5897, 8912, 8913, 8914, 18823, 18824, 40891 }

最も単純なアプローチは、C ++ std :: setのようなバランスのとれたバイナリツリーを使用することですが、それを使用して、私はしばしば数値の実行があるという事実を利用していません。おそらく、範囲のコレクションを格納する方が良いでしょうか?しかし、これは、範囲内の整数が削除された場合、または2つの範囲間のスペースが埋められた場合に結合された場合、範囲を分割できる必要があることを意味します。

この問題に適している既存のデータ構造はありますか?

回答:


9

葉に間隔(連続した整数の連続)を含めることができるように拡張されたバイナリ検索ツリーを使用することをお勧めします。間隔がオーバーラップせず、順序が合っているという不変式を維持します(検索ツリー不変式に従います)。(これは、間隔が重ならない特殊な場合のために、間隔ツリーまたはセグメントツリーの特殊なケースと考えることができます。)

Olg65535Olg


5

まず第一に、「迅速に」はあまり意味がないので、他の理由がない限り、あなたの質問は非常に不適切な言葉遣いです。「クイック」が何を意味するかについて、いくつかのメトリックを提供する必要があります。

それ以上に、問題のデザインを考え出そうとするときは、まず問題を非常によく理解し、多くの追加の質問をする必要があります。この場合の関連する質問は次のようです(順不同)。

  • これらすべての操作は同じように迅速でなければなりませんか、それとも他のものより重要なものがありますか?
  • 他の考慮事項はありますか?
  • 記憶はまったく心配ですか?
  • 複数のスレッドから挿入、削除、ルックアップを実行できるかどうかは問題ですか?
  • ワークロードは主に挿入に集中していますか?削除しますか?見上げる?

[065535]

もう少し作業が必要な場合は、データを8192整数のビットとして格納することで速度を犠牲にして、スペースを節約できます。概念的には、単一の整数演算は依然として一定時間であり、範囲付き整数演算は依然として線形時間ですが、それらは遅くなります。

したがって、これが本当にあなたの問題である場合は、配列を使用して、コードで他のより重要なことに移ります。

[065535]


3

U={0あなた1}Oログログあなた

データの構造によっては、データを保存するための賢明な代替手段がたくさんあるかもしれません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.