Harry
Harry

Reputation: 3052

equality comparison of two std::unordered_map fails

How to check for equality of two std::unordered_map using std::equal to check if both containers have same keys and their corresponding key values. Below my code prints unequal even though both containers have same size, set of keys and the corresponding key values are equal.

#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() && std::equal(um1.begin(), um1.end(), um2.begin()))
        std::cout << "equal" << std::endl;
    else
        std::cout << "unequal" << std::endl;
}

Upvotes: 2

Views: 3458

Answers (2)

Ricardo Veloz
Ricardo Veloz

Reputation: 19

Due to the nature of the unordered containers they do not have a fix order, the reason is the hash, even if they have the same keys and values

Here is code:

for (auto it = permutation1.begin(); it != permutation1.end(); it++)
{
    if (permutation2.count(it->first)) {
        
        
        int cantidad = permutation2[it->first];

        if (it->second != cantidad)
        {
            cout << "Is NOT" << endl;
            return false;
        }
    }
    else {
        cout << "Is NOT " << endl;
        return false;
    }
}
    cout << "Is" << endl;
return true;

Upvotes: 0

Kenny Ostrom
Kenny Ostrom

Reputation: 5871

https://en.cppreference.com/w/cpp/algorithm/equal

Two ranges are considered equal if they have the same number of elements and, for every iterator i in the range [first1,last1), *i equals *(first2 + (i - first1)).

Consider this code added to your code snippet:

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: 1

o: 1
r: 1
f: 1

Note that the iteration happens in a different order, as you should expect. Therefore they are not std::equal because (as documented above) that expects the same values in the same order.

However, this specitic container has its own operator== as noted in the comments, which checks for value equality as you were originally expecting for this specific container.

Upvotes: 4

Related Questions