web-dev-qa-db-ja.com

これらのディクショナリメソッドの複雑さは何ですか?

次のDictionaryメソッドの複雑さは誰にも説明できますか?

ContainsKey(key)
Add(key,value);

私が書いた方法の複雑さを理解しようとしています:

public void DistinctWords(String s)
{
    Dictionary<string,string> d = new Dictionary<string,string>();
    String[] splitted = s.split(" ");
    foreach ( String ss in splitted)
    { 
        if (!d.containskey(ss))
            d.add(ss,null);
    } 
}

2つのディクショナリメソッドはlog(n)複雑であると想定しました。ここで、nはディクショナリ内のキーの数です。これは正しいです?

22
Dan Dinu

このルーチンは、全体として、事実上O(m)時間の複雑さであり、mは検索内の文字列の数です。

Dictionary.ContainsDictionary.Add は両方とも(通常)O(1)演算であるためです。

(Dictionary.AddはO(n)のように、Dictionaryのn個のアイテムで使用できるため、それよりも少し複雑ですが、辞書の容量が小さい場合のみです。したがって、十分な容量のある辞書は、O(m))になります。)

そうは言っても、存在チェックにディクショナリのみを使用している場合は、HashSet<string>。これはあなたが書くことを可能にするでしょう:

  public void DistinctWords(String s)
  {
     HashSet<string> hash = new HashSet<string>(s.Split(' '));

     // Use hash here...

ディクショナリはローカル変数であり、(少なくともコードには)保存されていないため、LINQを使用することもできます。

 var distinctWords = s.Split(' ').Distinct();
14
Reed Copsey

Dictionary ...のドキュメントに記載されています.

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

そして Add 関数の場合:

カウントが容量より少ない場合、このメソッドはO(1)演算に近づきます。新しい要素に対応するために容量を増やす必要がある場合、このメソッドはO(n)操作。nはCountです。

34
Reddog

どちらの方法にも一定の複雑さがあります。

  • ContainsKey(key)-O(1)
  • Add(key、value)-O(1)
14
Darin Dimitrov

それは正しくありません。通常、辞書/ハッシュテーブルの検索はO(1)です。これを行うには、探しているキーからハッシュを生成し、それを同じハッシュを持つアイテムとのみ比較します-優れたハッシュアルゴリズムを使用すると、これはO(1)全体と見なされます( 償却済み O(1)-O(n)がある追加のために容量を増やす必要があるまれな場合のみ)。

7
BrokenGlass

どちらも一定の時間です:

http://msdn.Microsoft.com/en-us/library/kw5aaea4.aspx

http://msdn.Microsoft.com/en-us/library/k7z0zy8k.aspx

ただし、1つの注意点があります。

「カウントが容量より少ない場合、このメソッドはO(1)演算に近づきます。新しい要素に対応するために容量を増やす必要がある場合、このメソッドはO(n)操作、nはカウントです。 "

2
aquinas

ContainsKeyおよびAddメソッドはO(1)に近いです。

ContainsKeyのドキュメント:

このメソッドは、O(1)演算に近づきます。

ドキュメントを追加:

カウントが容量より少ない場合、このメソッドはO(1)演算に近づきます。新しい要素に対応するために容量を増やす必要がある場合、このメソッドはO(n)操作。nはCountです。

Framework 3.5以降を使用している場合は、HashSet<T>ダミー値を持つ辞書の代わりに:

public void DistinctWords(String s) {
  HashSet<string> d = new HashSet<string(s.split(" "));
}
2
Guffa