Подтвердить что ты не робот

В чем сложность этих методов словаря?

Может ли кто-нибудь объяснить, в чем сложность следующих методов 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 - количество ключей в словаре. Правильно ли это?

4b9b3361

Ответ 1

Эта процедура, в целом, является, по сути, временной сложностью O (m), при которой m является числом строк в вашем поиске.

Это связано с тем, что Dictionary.Contains и Dictionary.Add являются (как правило) операциями O (1).

(Это немного сложнее, поскольку Dictionary.Add может быть O (n) для n элементов в словаре, но только тогда, когда емкость словаря мала. Таким образом, если вы создаете словарь с достаточно большой емкостью фронт, это будет O (m) для 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();

Ответ 2

Это написано в документации для Словарь...

Общий класс словаря предоставляет сопоставление от набора ключей к набору значений. Каждое дополнение к словарю состоит из значения и связанного с ним ключа. Получение значения с помощью его ключа очень быстро, близко к O (1), потому что класс Dictionary реализован как хеш-таблица.

И для функции Добавить:

Если значение Count меньше емкости, этот метод приближается к операции O (1). Если емкость должна быть увеличена для размещения нового элемента, этот метод становится операцией O (n), где n является Count.

Ответ 3

Оба метода имеют постоянную сложность:

  • ContainsKey (ключ) - O (1)
  • Добавить (ключ, значение) - O (1)

Ответ 4

Это неверно, обычно словари/хэш-таблица - это O (1). Для этого он генерирует хэш из ключа, который вы ищете, и сравниваете его только с элементами, имеющими один и тот же хеш - с хорошим алгоритмом хэширования это считается O (1) в целом (amortized O (1) - только в редких случаях, когда емкость должна быть увеличена для добавления, у вас есть O (n)).

Ответ 5

Оба являются постоянными:

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

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

Одно предупреждение:

"Если значение Count меньше емкости, этот метод приближается к операции O (1). Если емкость должна быть увеличена для размещения нового элемента, этот метод становится операцией O (n), где n является Count."

Ответ 6

Метод ContainsKey и Add близок к O (1).

Содержит документацию по запросу:

Этот метод приближается к операции 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(" "));
}