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.
Related
Since std::set cannot contain duplicate elements and is always sorted, std::set::equal_range will always return the range that has either none or 1 element. Technically, yes, that's still a range, but what is the purpose of this algorithm? For std::set it seems pretty unnecessary.
I'm only guessing. But, like count(), it has some value when you're in a template and don't want to have to determine whether you're operating on a std::set or some other associative container.
Basically, it's for consistency. The function does perform as advertised, it's just that yes it has questionable use versus something like find() if you take it in isolation. It does potentially save you one manual iterator increment if you really do want a half-open range out of the box though. :P
All of the associative containers support equal_range, which means you can write generic code which accepts a set, multiset, map or multimap and it will do the right thing.
Consider std::multiset. Despite practically identical in interface, it can contain equal_ranges of higher lengths.
is there, in the c++ "Standard Library", any "Associative" (i.e. "Key-Value") Container/Data Structure, that has the ability, to preserve order, by order of insertion?
I have seen several topics on this, however, it seems, most before C++11.
Some suggest using "boost::multi_index", but, if at all possible, I would "rather" use standard containers/structures.
I see that C++11 has several, apparently, "unordered" associative containers :link.
Are any of these, by some way, "configurable", such that they are only sorted by insertion order?
Thanks!
C
No.
You are mixing linear access with random. Not very good bed fellows.
Just use both a vector/list (i.e. order of insertion) along with a map using an index into the former.
No; such capability was apparently sacrificed in the name of performance.
The order of equivalent items is required to be preserved across operations including rehashes, but there's no way to specify the original order. You could, in theory, use std::rotate or the like to permute the objects into the desired order after each insertion. Obviously impractical, but it proves the lack of capability is a little arbitrary.
Your best bet is to keep the subsequences in inner containers. You may use an iterator adaptor to iterate over such a "deep" container as if it were a single sequence. Such a utility can probably be found in Boost.
No.
In unordered maps too, there are not stored according to the order of insertion.
You can use vector to keep the track of the key!
I have a lot of lists, vectors, sets ... (what ever you prefer) of pointers called RealAlgebraicNumberPtr to certain class. They are sorted.
I want to merge them and of course I want to do it fast and efficient.
What is the best choice? std::merge ? Or maybe std::set? I can provide both an < and == ordering.
Any ideas?
As mentioned, std::merge is ok.
Only for std::list, you can profit from the optimization that std::list::merge member function implements: it splices the list nodes from the source into the target. That way, the source list will become empty, but it will avoid resource (re)allocation
Re: std::set
you could in fact std::merge into a std::set to get unique values in one go. With generic merge, duplicate values are not filtered, but the result is sorted, so you could apply std::unique to the result. If you expect a lot of duplicates, you might be quicker using a std::set
std::merge is as efficient as it gets. Which underlying container you use depends on your requirements. std::vector has the smallest memory-overhead of all standard containers, so if your data are large, you should stick with that.
If you use std::vector, you should resize the target-vector before merging to avoid reallocations (you should be able to calculate the required size up-front), instead of using an std::back_inserter.
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.
I've got a situation where I want to use an associative container, and I chose to use a std::unordered_map, because it's perfectly feasible that this container could be used to hold millions or more of elements. But now I also need to iterate in order. I considered having the value types link to each other in a list, but now I'm going to have issues with memory management.
Should I change container, say to a std::map? Or just iterate once through my unordered_map, insert into a vector, and sort, then iterate? It's pretty unlikely that I will need to iterate in an ordered fashion repeatedly.
Well, you know the O() of the various operations of the two alternatives you've picked. You should pick based on that and do a cost/benefit analysis based on where you need the performance to happen and which container does best for THAT.
Of course, I couldn't possibly know enough to do that analysis for you.
You could use Boost.MultiIndex, specifying the unordered (hashed) index as well as an ordered one, on the same underlying object collection.
Possible issues with this - there is no natural mapping from an existing associative container model, and it might be overkill if you don't need the second index all the time.