Неупорядоченные вопросы

Кто-нибудь может объяснить, как работает неупорядоченный набор? Я также не уверен, как работает набор. Мой главный вопрос - какова эффективность его функции поиска.

Например, каково общее время выполнения этого большого O?

    vector<int> theFirst;
    vector<int> theSecond;
    vector<int> theMatch;

    theFirst.push_back( -2147483648 );
    theFirst.push_back(2);
    theFirst.push_back(44);


    theSecond.push_back(2);
    theSecond.push_back( -2147483648 );
    theSecond.push_back( 33 );


    //1) Place the contents into a unordered set that is O(m). 
    //2) O(n) look up so thats O(m + n). 
    //3) Add them to third structure so that's O(t)
    //4) All together it becomes O(m + n + t)
    unordered_set<int> theUnorderedSet(theFirst.begin(), theFirst.end());

    for(int i = 0; i < theSecond.size(); i++) 
    {
        if(theUnorderedSet.find(theSecond[i]) != theUnorderedSet.end()) 
        {
        theMatch.push_back( theSecond[i] );
        cout << theSecond[i];
        }
   }

2 ответа

unordered_set и все остальные unordered_ структуры данных используют хеширование, как упомянуто @Sean. Хеширование включает в себя амортизированное постоянное время для вставки и близко к постоянному времени для поиска. Хеш-функция, по сути, берет некоторую информацию и выдает из нее число. Это функция в том смысле, что один и тот же вход должен давать одинаковый результат. Однако разные входные данные могут приводить к одному и тому же выходному сигналу, что приводит к столкновению. Поиск гарантированно будет постоянным временем для "идеальной хэш-функции", то есть без коллизий. На практике входной номер берется из элемента, который вы храните в структуре (скажем, его значение, это примитивный тип), и сопоставляет его с местоположением в структуре данных. Следовательно, для данного ключа функция переносит вас в место, где хранится элемент, без необходимости каких-либо обходов или поисков (игнорируя столкновения здесь для простоты), следовательно, с постоянным временем. Существуют различные реализации этих структур (открытая адресация, цепочка и т. Д.). См. Хэш-таблицу, хэш-функцию. Я также рекомендую раздел 3.7 Руководства по разработке алгоритмов Skiena. Теперь, что касается сложности big-O, вы правы в том, что у вас есть O(n) + O(n) + O(размер перекрытия). Поскольку перекрытие не может быть больше, чем меньшее из m и n, общая сложность может быть выражена как O(kN), где N является наибольшим между m и n. Скоро). Опять же, это "лучший случай", без коллизий и с идеальным хешированием.

set а также multi_set с другой стороны, используйте двоичные деревья, поэтому вставки и поиски обычно O (logN). Фактическая производительность хешированной структуры по сравнению с бинарным деревом зависит от N, поэтому лучше всего попробовать два подхода и профилировать их в реалистичном сценарии работы.

Все типы данных std::unordered_*() используют хеш для поиска. Посмотрите документацию Boost по этому вопросу, и я думаю, вы очень быстро получите понимание.

http://www.boost.org/doc/libs/1_46_1/doc/html/unordered.html

Другие вопросы по тегам