I need to check if two std::maps contain the same keys and values so I need a way to access the key value pairs of both std::maps. I know that std::maps have the == operator but my std::map contains objects in the value field that don't have a defined == operator. It would also be too difficult to make an == operator for the object because it contains pointers to other objects I would need to define == for.
Is there a way of getting key value pairs without iterators or a better way of trying to do what I'm describing?
Related
This question already has answers here:
Use cases of std::multimap
(3 answers)
Closed 6 months ago.
I've just started learning STL containers, and I cannot understand why std::multimap exists. With std::map, we can access values by user-defined keys, but with std::multimap we cannot do that as the latter does not even have an overloaded operator[] and the same key can be mapped to several different values. To me, this looks like std::multimap is essentialy just something like std::multiset<std::pair<K, V>> with the Compare function operating on the K and we lose the main feature of a map which is the ability to access elements by key (as I see it). I've found this post, but still couldn't comprehend the usecases given here. Could someone please give me several examples when we would use std::multimap?
First note that std::map::operator[] is a little quirky. It is not the way to access elements in the map. Instead std::map::operator[] potentially inserts an element into the map and then returns a reference to either the element that was already present before or to the newly inserted. This may seem like splitting hairs, but the difference matters. The way to access a mapped_value given a key in a std::map is std::map::find. std::multimap has a find as well. No big difference with respect to that.
std::map::at has not counterpart in std::multimap because std::map::at returns a reference to the mapped_value for the given key, but in the multimap there can be more than one mapped_value for the same key, so it isnt obvious what a std::multimap::at should return if it existed. Finding and accessing elements can be done with find for both maps.
A std::multimap<K,V> can be compared to a std::map<K,std::vector<V>> but with the interface you'd expect when you want to map more than a single value to the same key. For example std::multimap iterators lets you iterate all key-value pairs in the multimap in one go. With the map of vectors you'd have to use the maps iterators and the vectors iterators. Using the map of vectors with standard algorithms is rather cumbersome.
Further, std::multimap::count returns the number of elements for a given key. With the map of vectors you would have to first find the vector for given key and call its size. This list is not complete, but I hope the difference gets clear.
One example for a multimap could be inhabitants of houses. In the same house lives more than one person. If you want to map street number to person you could use a multimap.
More generally, if you have a collection / container of elements and you want to divide them into distinct groups, you can use a multimap. A common use of std::map (or std::unordered_map) is to count frequencies, eg:
std::map<int,int> freq;
for (const auto& x : some_container) {
++freq[ x % 3 ];
}
This counts how many elements of some_container are divisible by 3, without remainder, with remainder 1, or with remainder 2. If you want to know the elements rather than only count them you can use a std::multimap.
I understand that the map type in C++ automatically sorts its entries by the key. However, how does it handle breaking ties? Does it then sort according to value?
The comparator for C++ map and multimap only sees the keys, not the values. There is no need to "break ties": two keys are considered equal if and only if neither one compares less than the other.
I want to write a comparison object for my multimap which is sorted according to keys and if two keys are equal then according to their value.
Problem I am facing is that that inbuilt library of multimap passes only key in comparison object and not value.
Please, can someone help me how can I do this..
I'm having a hard time wrapping my head around unordered_maps and unordered_multimaps because my test code isn't producing what I've been told to expect.
std::unordered_map<string, int> names;
names.insert(std::make_pair("Peter", 4));
names.insert(std::make_pair("George", 4));
names.insert(std::make_pair("George", 4));
When I iterate through this list, I get one instance of George first, then Peter.
1) It's my understanding unordered_maps do not allow multiple keys to map to one value, and that multimaps due. Is this true?
2) Why can Peter and George coexist at a value of 4? What is happening to the second George? And for that matter, why is George appearing first when I iterate from begin() to end() if this is unordered?
3) What is the underlying representation of an unordered map vs. unordered multimap?
4) Is there a way to insert keys into either map without providing a value? E.g. have the compiler create its own hash function that I don't need to worry about when I retrieve keys and look for collisions?
I'll make it short:
No. Multi... refers to keys. A (non-multi)map can't have multiple equivalent keys with differeny values, ie. per key there is at most one value. A multi map can. The same holds for the unordered versions.
Peter != George, which is why they have different key and may very well have the same value.
A hashmap.
Use sets.
In your example the second insertion for George using a (non-multi) is skipped as the same key was previously inserted.
You want to use unordered_multimap to have several keys that are the same.
Since this is unordered you can't really hope to have any particular order, because it depends on the hash function.
If you want order in which you insert things, you need to use std::vector. Even normal maps, which are supposed to be ordered imply the comparison order, and not the order in which you insert things, for example string "AB" comes before "BB", because "A" is less than "B".
To insert without providing a value you need a set, and not a map.
The underlying structure of "unordered_" things is hashtable.
I was reading about c++ multimap and it states that multimap allows inserting duplicate Keys.This makes me think that a multimap uses a hashmap for underneath implementation (since a hashmap allows duplicates incase of collision) then I also read that unordered map uses a hash map. My question is then whats the difference between the two. I tried looking for comparison between the two but I could not find anything that would explain this.
A hash table permits and resolves collisions of hash values. It only stores one copy of each key value (as determined by operator== or another equality relation). But if two distinct keys hash to the same value (bound to happen), that is handled by collision resolution. For each key, there is a single value.
A multimap is an ADT that associates multiple values with each key instead of one. It's not a particular implementation strategy: It can internally use a hash table, a search tree, or something completely different.