#c
#c
Вопрос:
Как проверить равенство двух std::unordered_map
, используя std::equal
для проверки, имеют ли оба контейнера одинаковые ключи и соответствующие им значения ключей. Ниже мой код печатается unequal
, даже если оба контейнера имеют одинаковый размер, набор ключей и соответствующие значения ключей равны.
#include <iostream>
#include <unordered_map>
int main() {
std::unordered_map<char, int> um1, um2;
um1['f'] = 1;
um1['o'] = 1;
um1['r'] = 1;
um2['o'] = 1;
um2['r'] = 1;
um2['f'] = 1;
if (um1.size() == um2.size() amp;amp; std::equal(um1.begin(), um1.end(), um2.begin()))
std::cout << "equal" << std::endl;
else
std::cout << "unequal" << std::endl;
}
Комментарии:
1.
If (um1 == um2)
?2. имейте в виду, что это неупорядоченная карта, поэтому порядок, в котором итераторы будут перебирать ключи, не указан и может казаться случайным. Это будет работать с a
std::map
, поскольку оно будет сортировать свои элементы согласованным образом. Ноstd::unordered_map
реализован как hashmap, поэтому порядок, в котором вы получите элементы, зависит от хэш-функции, размера корзины и порядка вставки. (это также может измениться в дальнейшем, если произойдет перефразирование)3. Обратитесь к этому — cplusplus.com/reference/unordered_map/unordered_map/operators
4. @NathanOliver это дает мне требуемый результат. Работает ли это для любого порядка вставки?
5. @Harry operator== будет работать для любого порядка вставки. однако имейте в виду, что сравнение двух unordered_maps может быть намного дороже, чем сравнение двух карт нормалей (из-за их несортированного характера) — сравнение
std::map
s будет не болееO(n)
, в то время как сравнениеstd::unsorted_map
s может быть доO(n²)
. (где n — количество элементов в карте)
Ответ №1:
https://en.cppreference.com/w/cpp/algorithm/equal
Два диапазона считаются равными, если они имеют одинаковое количество элементов и для каждого итератора i в диапазоне [first1,last1), *i равно *(first2 (i — first1)).
Считайте, что этот код добавлен в ваш фрагмент кода:
for (auto it : um1)
std::cout << it.first << ": " << it.second << std::endl;
std::cout << std::endl;
for (auto it : um2)
std::cout << it.first << ": " << it.second << std::endl;
f: 1
o: 1
r: 1o: 1
r: 1
f: 1
Обратите внимание, что итерация выполняется в другом порядке, как и следовало ожидать. Поэтому они не являются std::equal, потому что (как описано выше), который ожидает одинаковые значения в том же порядке.
Однако этот конкретный контейнер имеет свой собственный operator==, как указано в комментариях, который проверяет равенство значений, как вы изначально ожидали для этого конкретного контейнера.