This question already has answers here:
Find mapped value of map
(6 answers)
Closed 1 year ago.
std::unordered_map::find search for the certain key in the unordered_map, and is there a function to search a certain value?
Definitely I can write some simple loop to do it but maybe something already exist for that that?
No, not really. The map entries (key-value pairs) are not arranged according to their values; nor are the values stored separately from the keys etc. Or rather - the standard doesn't guarantee any of that, and all popular implementations don't offer this.
You're just going to have to use a linear search... or a different/additional data structure which supports the kind of searches you need.
Also remember that std::unordered_map is quite slow in practical, non-asymptotic terms, so if performance is a consideration - definitely look for alternatives.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 months ago.
The community reviewed whether to reopen this question 9 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I have a list of unsigned shorts that act as local IDs for a database. I was wondering what is the most memory-efficient way to store allowed IDs. For the lifetime of my project, the allowed ID list will be dynamic, so it may have more true or more false allowed IDs as time goes on, with a range of none allowed or all allowed.
What would be the best method to store these? I've considered the following:
List of allowed IDs
Bool vector/array of true/false for allowed IDs
Byte array that can be iterated through, similar to 2
Let me know which of these would be best or if another, better method, exists.
Thanks
EDIT: If possible, can a vector have a value put at say, index 1234, without all 1233 previous values, or would this suit a map or similar type more?
I'm looking at using an Arduino with 2k total ram and using external storage to assist with managing a large block of data, but I'm exploring what my options are
"Best" is opinion-based, unless you are aiming for memory efficiency at the expense of all other considerations. Is that really what you want?
First of all, I hope we're talking <vector> here, not <list> -- because a std::list< short > would be quite wasteful already.
What is the possible value range of those ID's? Do they use the full range of 0..USHRT_MAX, or is there e.g. a high bit you could use to indicate allowed ones?
If that doesn't work, or you are willing to sacrifice a bit of space (no pun intended) for a somewhat cleaner implementation, go for a vector partitioned into allowed ones first, disallowed second. To check whether a given ID is allowed, find it in the vector and compare its position against the cut-off iterator (which you got from the partitioning). That would be the most memory-efficient standard container solution, and quite close to a memory-optimum solution either way. You would need to re-shuffle and update the cut-off iterator whenever the "allowedness" of an entry changes, though.
One suitable data structure to solve your problem is a trie (string tree) that holds your allowed or disallowed IDs.
Your can refer to the ID binary representation as the string. Trie is a compact way to store the IDs (memory wise) and the runtime access to it is bound by the longest ID length (which in your case is constant 16)
I'm not familiar with a standard library c++ implementation, but if efficiency is crucial you can find an implementation or implementat yourself.
This question already has answers here:
Is the order of items in a hash_map/unordered_map stable?
(2 answers)
Closed 7 years ago.
Context: I need this data structure to find the keywords of a particular file at a node. So the map is having file name and vector to store the keywords of that file.This is basically a small code i am using in mpi to find relationship between files at different nodes in a parallel fashion.
The order of the elements of an std::unordered_map is not stable, which explains your output.
Read this answer for more and how to read the elements. Also next time search before asking a question and of course (almost) never post images of code, but use code tags.
From the ref:
Internally, the elements are not sorted in any particular order, but organized into buckets.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How is a C++ multimap implemented?
C++ reference mentions
Multimaps are typically implemented as binary search trees.
But what is their typical internal representation?
Is it like std::map<Key, std::list<Value> > or similar?
My concern is complexity of insertion and iteration over a set of elements with the same key.
If you want to know the complexity of specific operations, you need look no further than to the standard. The standard has guarantees on the complexity, but implementations are free to satisfy those guarantees any way they wish.
For insertion the complexity is O(lg n), unless you specify an optimal hint every time, in which case the complexity is O(1) amortized. (See details here: http://en.cppreference.com/w/cpp/container/multimap/insert)
For iteration over a set of elements with the same key, the complexity is the same as iteration from any iterator to another. Given that you have already found the iterators, the iteration is linear in the count of items you are iterating over. (Sorry, unable to find a reference for this right now)
I'm looking for either a ready made associative map container that supports multiple keys (aliases) that map to a single value.
If there's no ready made solution, am I likely to have to resort to using 2 separate maps or is there a better way?
It seems the std::multimap is the reverse of what I want.
This question that is much the same has an accepted answer of boost::multi_index, but I've had a look at the documentation and am completely baffled on how to use it.
If the multi_index can help me implement this, does anyone have an example??
I have a map with about 100,000 pairs . Is there any way that i can speed up searching when using find(), given that the keys are in alphabetical order. Also how should i go about doing it. I know that you can specify a new comparator when you create the map. But will that speed up the find() function at all?
Thanks in advance.
[solved] Thanks a bunch guys i have decided to go with a vector and use lower and upperbound to "snip" some of the searching.
Also i am new here is there any way to mark this question as answered , or pick a best answer?
A different comparator will only speed up find if it manages to do the comparison faster (which, for strings will usually be pretty difficult).
If you're basically inserting all the data in order, then doing the searching, it may be faster to use a std::vector with std::lower_bound or std::upper_bound.
If you don't really care about ordering, and just want to find the data as quickly as possible, you might find that std::unordered_map works better for you.
Edit: Just for the record: the way you "might find" or "may find" those things is normally by profiling. Depending on the situation, it might be enough faster that it's pretty obvious even in simple testing, so profiling isn't really necessary, but if there's (much) doubt, or you want to quantify the effect, a profiler is probably the right way to do it.
std::map is already taking advantage of the fact the keys are in alphabetical order - it guarantees that itself. You aren't going to be able to improve it by changing the comparator (one assumes it's already a reasonably efficient string comparison).
Have you considered using unordered_map (aka hash_map in various implementations pre C++11? It should be able to search in O(1) instead of O(log(n)) for std::map.
You could also look into something slightly more exotic, like a trie, but that's not part of the standard library so you'd either have to find one elsewhere or roll your own, so I'd suggest unordered_map is a good place to start.
If you're using std::find to find elements, you should switch to using map::find (you don't really say in your question.) map::find uses the fact that the map is ordered to search much faster.
If that's still not good enough, you might look into a hash container such as unordered_map rather than map.
I've put in a vote for unordered_map but I wanted to also make another point.
One of the things that can hurt performance on modern machines is poor use of the cache. A map is going to have nodes allocated all over the place and there won't be much locality of reference. Also since it has to store a bunch of pointers between nodes it will use up more memory.
At the recent Going Native 2012 conference Bjarne Stroustroup gave an interesting talk that touched on this topic. He compared vector and list performance at a task involving a lot of random insertions and deletions, where it might seem list ought to have dominated, but because of the memory size and layout issue vector was in fact the fastest by far. Take a look at his slides, starting at slide 43.
unordered_map gives you direct access to the element and so it probably means even less hopping around in memory than trying to stick your data in a vector (and thus better performance than vector) so my comment is simply an admonishment to always keep your memory access pattern in mind for performance