I need help iterating over an unordered map in C++. I am trying to put the elements of the set into an array so that I can sort the array.
for(auto it=s.begin();it!=s.end();it++){
a[i]=*it;
i++;
}
Your are using many differen terms here.
unordered_set
unordered_map
set
array
So, it is a little bit unclear what you really want to do.
If you have a std::unordered_setand want to put the data into a std::set, then you can simply use its range constructor and write something like std::set<int> ordered(s.begin(),s.end());
The same would work with a std::vector which has also a range constructor. Arrays, either C-style or C++ std::array are more complicated, because you need to know the size of the original data in advance. Because: Arrays have a compile time definde fixed size.
For sorting std::maps or std::unordered_maps according to their "value" and not the key, you need to use a std::multiset with a special sorting functor or lambda. If you edit your question and give more details, then I will provide source code to you.
Related
I have an std::set, which stores std::pairs of two integers. The std::set is also sorted, by allowing me to pass a helping class. However, I have written many lines of code so far and now, at the last tests, "they" told me something, that actually means that I need to allow possible duplicates in the std::set. Of course this isn't done with std::set. Any alternative that will not make me change the whole-big project?
In short, I use the std::set as an ordered list with data an std::pair of two ints.
You can use std::multiset. That should work for what you are describing.
std::multiset is the answer, as suggested by WhozCraig.
Can I create an std::vector using my pre-existing data instead of it allocating new memory and copying the data?
To be clearer, if I have a memory area (either a c-array or part of another vector or whatever) and I want to provide vector-like access to it, can I create a vector and tell it to use this block of memory?
No, but you could write your own class that does this. Since this would be a fairly common need I wouldn't be surprised if someone else has done this already.
However the normal C++ way would be to write template code to operate on iterators. You can create iterators for any portion of a vector, or for any portion of a C array (and much else). So writing template code for iterators is probably what you should be doing.
Since you can use a custom allocator when creating a vector, it is technically possible.
However, I wouldn't recommend it. I'd just create a vector with a fixed size (apparently you can get a hold of that) and then use std::copy.
Algorithms which iterate over a container accept a pair of iterators which define the input range. You can use the algorithm with iterators which point to a middle of a big container.
Examples:
std::vector<int> big_vector(100000);
// initialize it
//...
std::sort(big_vector.begin()+100, big_vector.begin()+200); // sort a subrange
int big_array[100000]; //c-style array
// initialize it
//...
std::sort(std::begin(big_array)+300, std::begin(big_array)+400); // sort a subrange
From C++20 we have std::span which provides the exact same thing you are looking for. Take a look at https://en.cppreference.com/w/cpp/container/span.
I am confused. I don't know what containers should I use. I tell you what I need first. Basically I need a container that can stored X number of Object (and the number of objects is unknown, it could be 1 - 50k).
I read a lot, over here array vs list its says: array need to be resized if the number of objects is unknown (I am not sure how to resize an array in C++), and it also stated that if using a linked list, if you want to search certain item, it will loop through (iterate) from first to end (or vice versa) while an array can specify "array object at index".
Then I went for an other solution, map, vector, etc. Like this one: array vs vector. Some responder says never use array.
I am new to C++, I only used array, vector, list and map before. Now, for my case, what kind of container you will recommend me to use? Let me rephrase my requirements:
Need to be a container
The number of objects stored is unknown but is huge (1 - 40k maybe)
I need to loop through the containers to find specific object
std::vector is what you need.
You have to consider 2 things when selecting a stl container.
Data you want to store
Operations you want to perform on the stored data
There wasa good diagram in a question here on SO, which depitcs this, I cannot find the link to it but I had it saved long time ago, here it is:
You cannot resize an array in C++, not sure where you got that one from. The container you need is std::vector.
The general rule is: use std::vector until it doesn't work, then shift to something that does. There are all sorts of theoretical rules about which one is better, depending on the operations, but I've regularly found that std::vector outperforms the others, even when the most frequent operations are things where std::vector is supposedly worse. Locality seems more important than most of the theoretical considerations on a modern machine.
The one reason you might shift from std::vector is because of iterator validity. Inserting into an std::vector may invalidate iterators; inserting into a std::list never.
Do you need to loop through the container, or you have a key or ID for your objects?
If you have a key or ID - you can use map to be able to quickly access the object by it, if the id is the simple index - then you can use vector.
Otherwise you can iterate through any container (they all have iterators) but list would be the best if you want to be memory efficient, and vector if you want to be performance oriented.
You can use vector. But if you need to find objects in the container, then consider using set, multiset or map.
I've constructed a map which has a vector as its key: map<vector<KeyT>, T> which I'm trying to optimize now.
An experiment with manually nested maps map<vector<KeyT>, map<KeyT,T> > where the first key is the original vector minus the last element and the second key is the last element shows a reasonable speed-up.
Now I'm wondering whether there exists a semi-standard implementation (like boost or similar) of an associative container where vector keys are implemented as such a hierarchical structure of containers.
Ideally, this would create as many layers as there are elements in the key vector, while keeping a uniform syntax for vectors of different length.
Are you sure you need to optimise it? std::string is basically like a std::vector and we happily use std::string as an array key!
Have you profiled your code? std::map doesn't copy its key/value pairs unneccesarily -- what exactly are you afraid of?
Are your vector keys of a fixed-size? std::tuple might help in that case.
If not, it might help to partition your containers according to the length of the key, although the effectiveness of schemes such as this are highly domain-dependent.
My first hunch is that you want to improve map lookup time by reducing the volume of the key. This is what hash functions are for. C++ tr1 and Boost have hash_maps by the name of unordered_map
I'll try to devise a small sample in some time here
how to remove duplicate values from
std::vector <std::pair<UnicodeString, UnicodeString> > myVect;
Is there any built in function or i need to write a custom code for this
Assuming that (a) a std::set is not what you want [that is you want to allow duplicate elements in your std::vector, only to remove them later] and (b) you don't wish to change the order of the elements in your std::vector [that is, the current order is important], which are both reasonable situations... You should be able to adapt Fred Nurk's answer to How can I remove duplicate values from a list in C++ buy substituting vector for list and modifying the less comparators accordingly.
The best way to do it, if you can modify the order in your vector is the following:
std::sort(myVect.begin(), myVect.end());
myVect.erase(std::unique(myVect.begin(), myVect.end()), myVect.end());
Just make sure UnicodeString accepts the < operator.
However, you may want to use a different structure such as std::set or std::unordered_set to have an unique guarantee at insertion.