web-dev-qa-db-fra.com

Quelle est la complexité de ces méthodes de dictionnaire?

Quelqu'un peut-il expliquer quelle est la complexité des méthodes Dictionary suivantes?

ContainsKey(key)
Add(key,value);

J'essaie de comprendre la complexité d'une méthode que j'ai écrite:

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);
    } 
}

J'ai supposé que les 2 méthodes du dictionnaire sont de complexité log (n) où n est le nombre de clés dans le dictionnaire. Est-ce correct?

22
Dan Dinu

Cette routine, dans son ensemble, est, en fait, O(m) complexité temporelle, avec m étant le nombre de chaînes dans votre recherche.

En effet, Dictionary.Contains et Dictionary.Add sont tous deux (normalement) O(1) operations).

(C'est légèrement plus compliqué que cela, car Dictionary.Add peut être O(n) pour n éléments dans le dictionnaire, mais uniquement lorsque la capacité du dictionnaire est petite. En tant que tel, si vous construisez votre dictionnaire avec une capacité suffisante à l’avance, ce serait O(m) pour m entrées de chaîne.)

Cela dit, si vous utilisez uniquement le dictionnaire pour vérifier l'existence, vous pouvez utiliser un HashSet<string>. Cela vous permettrait d'écrire:

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

     // Use hash here...

Comme votre dictionnaire est une variable locale et non stockée (au moins dans votre code), vous pouvez également utiliser LINQ:

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

C'est écrit dans la documentation pour Dictionary ...

La classe générique Dictionary fournit un mappage d'un ensemble de clés à un ensemble de valeurs. Chaque ajout au dictionnaire se compose d'une valeur et de sa clé associée. La récupération d'une valeur à l'aide de sa clé est très rapide, proche de O (1), car la classe Dictionary est implémentée comme une table de hachage.

Et pour la fonction Ajouter :

Si le nombre est inférieur à la capacité, cette méthode approche une opération O(1). Si la capacité doit être augmentée pour accueillir le nouvel élément, cette méthode devient un O(n), où n est Count.

34
Reddog

Les deux méthodes ont une complexité constante:

  • ContainsKey (clé) - O (1)
  • Ajouter (clé, valeur) - O (1)
14
Darin Dimitrov

Ce n'est pas correct, généralement la recherche de dictionnaires/table de hachage est O (1). Pour ce faire, il générera un hachage à partir de la clé que vous recherchez et ne le comparera qu'aux éléments qui ont le même hachage - avec un bon algorithme de hachage, cela est considéré O(1) global ( amorti O(1) - seulement dans les rares cas où la capacité doit être augmentée pour un ajout vous avez O (n)).

7
BrokenGlass

Les deux sont à temps constant:

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

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

Une mise en garde cependant:

"Si Count est inférieur à la capacité, cette méthode approche une opération O(1). Si la capacité doit être augmentée pour accueillir le nouvel élément, cette méthode devient un O(n), où n est Count. "

2
aquinas

Les méthodes ContainsKey et Add sont proches de O (1).

Contient une documentation clé:

Cette méthode approche une opération O(1).

Ajouter de la documentation:

Si le nombre est inférieur à la capacité, cette méthode approche une opération O(1). Si la capacité doit être augmentée pour accueillir le nouvel élément, cette méthode devient un O(n), où n est Count.

Si vous utilisez Framework 3.5 ou version ultérieure, vous pouvez utiliser un HashSet<T> au lieu d'un dictionnaire avec des valeurs fictives:

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