Равномерность std :: unordered_map зависит от порядка вставки

Если вы создаете два std::unordered_map используя один и тот же набор (не равных) пар ключ-значение, но вставляются в другом порядке (поэтому контейнеры содержат равные элементы, но потенциально в разных порядках), являются контейнерами, которые гарантированно будут равным, согласно оператору равенства ( operator==). Я предполагаю, что хэш-код и операторы равенства элементов контейнера удовлетворяют всем необходимым ограничениям на их реализацию.

Ответ 1

Да, они гарантированно вернутся в этом случае равными. Конкретная формулировка (из N4659, § [unord.req]/12) такова:

Два неупорядоченных контейнера a и b сравнивают равные, если a.size() == b.size() и для каждой группы эквивалентных ключей [Ea1, Ea2) полученной из a.equal_range(Ea1), существует группа с эквивалентными ключами [Eb1, Eb2) полученный из b.equal_range(Ea1), такой, что is_permutation(Ea1, Ea2, Eb1, Eb2) возвращает true.

Итак, если ключи (и связанные значения) в одном совпадают с другими (но, возможно, в другом порядке), он будет сравнивать равные.

Ответ 2

Из [unord.red]/12

Два неупорядоченных контейнера a и b сравнивают равные, если a.size() == b.size() и для каждой группы эквивалентных ключей [Ea1, Ea2) полученной из a.equal_range(Ea1), существует группа с эквивалентными ключами [Eb1, Eb2) полученный из b.equal_range(Ea1), такой, что is_permutation(Ea1, Ea2, Eb1, Eb2) возвращает true. [...]

Итак, пока ключи одинаковы, а размер одинаковый, контейнеры будут сравниваться одинаково независимо от того, в каком порядке находятся ключи.

Ответ 3

Ниже приведены цитаты из cppreference.com о std: unordered_map, operator ==,! = (Std :: unordered_map):

Содержимое двух неупорядоченных контейнеров lhs и rhs равно, если выполняются следующие условия:

  • lhs.size() == rhs.size()
  • каждая группа эквивалентных элементов [lhs_eq1, lhs_eq2), полученная из lhs.equal_range (lhs_eq1), имеет соответствующую группу эквивалентных элементов в другом контейнере [rhs_eq1, rhs_eq2), полученную из rhs.equal_range (rhs_eq1), которая обладает следующими свойствами:
    • std :: distance (lhs_eq1, lhs_eq2) == std :: distance (rhs_eq1, rhs_eq2).
    • std :: is_permutation (lhs_eq1, lhs_eq2, rhs_eq1) == true.

Обратите внимание, что:

Поведение не определено, если Key или T не являются EqualityComparable.

Поведение также не определено, если Hash и KeyEqual делают (до С++ 20) KeyEqual (поскольку С++ 20) не имеют такого же поведения на lhs и rhs, или если оператор == для Key не является уточнением раздела в группы эквивалентных ключей, введенные KeyEqual (то есть, если два элемента, которые сравнивают равные с использованием оператора ==, попадают в разные разделы)

Наконец, рассмотреть сложность:

Пропорционально N вызывает оператор == на value_type, вызывает предикат, возвращаемый key_eq, и вызывает хешер, возвращаемый hash_function, в среднем случае, пропорциональный N2 в худшем случае, где N - размер контейнера.

Поэтому, если обе неупорядоченные карты имеют одинаковый размер, и каждый ключ в одном из контейнеров ищет в другом плюсе, если он окажется найденным, тогда их значения сравниваются, тогда они считаются одинаковыми.