web-dev-qa-db-ja.com

C#辞書の効率

C#辞書は、何かが存在するかどうかなどを見つけるための簡単な方法です。ただし、それらがどのように機能するかについては質問があります。辞書の代わりにArrayListを使用するとします。 ContainsKey(または他の言語の同等のメソッド)を使用する代わりに、ArrayListをループして、そこに何かが存在するかどうかを確認します(またはデータがソートされている場合はバイナリ検索を実行します)。効率の違いは何ですか? ContainsKeyメソッドは、キーをループするよりも効率的な方法を使用して、検索対象が存在するかどうかを確認していますか?

私が持っているデータのタイプに対応し、そのデータセット用に特別に設計された特定のハッシュ関数を作成したとしましょう。そうです、そのハッシュ関数はデータをループするよりも確かに高速です。しかし、辞書は一般的です。 ContainsKeyメソッドは、取得するデータに固有のものではなく、一般的な検索メソッドです。

基本的に私が求めているのは辞書はプログラマーに役立ちます。それらには、多くのことを支援するメソッドが含まれており、文字列を整数や(キーと値)などと組み合わせます。しかし、効率に関しては、彼らは何を提供していますか? dictionaryArrayListstructs(string,int)の違いは何ですか

14
John Demetriou

Dictionary がC#でどのように実装されているかを確認するには、少し掘る必要があります- ほど明確ではありませんHashMap (ハッシュテーブル)または TreeMap (ソートされたツリー)(または ConcurrentSkipListMap -a スキップリスト ).

「備考」セクションを掘り下げる場合:

Dictionaryジェネリッククラスは、キーのセットから値のセットへのマッピングを提供します。辞書への各追加は、値とそれに関連付けられたキーで構成されます。キーを使用して値を取得するのは非常に高速で、O(1)に近くなります。これは、Dictionaryクラスがハッシュテーブルとして実装されているためです。

そして、それがあります。 ハッシュテーブル です。そこにウィキペディアの記事をリンクしていることに注意してください-かなり良い読み物です。衝突の解決に関するセクションを読むとよいでしょう。ルックアップがO(N)に展開される病理データセットを取得することは可能です(たとえば、挿入するすべてが何らかの理由でハッシュテーブルの同じハッシュ値またはインデックスに該当する場合、 ' linear probing )が残っています。

ディクショナリは汎用的なソリューションですが、具体的な型(ディクショナリなど)を渡すのではなく、インターフェイスを渡す必要があります。この場合、そのインターフェースはIDictionarydocs )です。これにより、自分のデータに最適な処理を行う独自の辞書実装を完全に作成できます。

さまざまな検索/包含の効率性については?

  • ソートされていないリストを歩く:O(N)
  • ソートされた配列のバイナリ検索:O(log N)
  • ソートされたツリー:O(log N)
  • ハッシュテーブル:O(1)

ほとんどの人にとって、ハッシュテーブルは必要なものです。

SortedDictionary が代わりに必要なものであることがわかります。

SortedDictionary<TKey, TValue>ジェネリッククラスは、O(log n)を取得するバイナリ検索ツリーです。nは、ディクショナリ内の要素の数です。この点で、これはSortedList<TKey, TValue>ジェネリッククラス。 2つのクラスは同様のオブジェクトモデルを持ち、どちらもO(log n)検索を備えています。

繰り返しになりますが、データ構造がデータで理想的に機能するものでない場合は、データに最適に機能するものを作成できるツール(インターフェース)が提供されます。

辞書自体は 抽象データ型 です。あなたは私に辞書を与え、私はそれで何ができるか、そして辞書であるという性質によって私が使用するためにそこにあるすべてのツールを知っています。 ArrayListを提供してくれたら、リストから項目を検索、挿入、または削除するための独自のコードを書いているはずです。これは私の時間を浪費するだけでなく、コードを何度も何度もコピーするときにバグが発生する可能性が高くなります。

22
user40980