I have a set of data which in some occasion I need to sort them in one way and some occasion in another way. For example, suppose the data set is a set of strings,{"abc", "dfg",...}. Sometimes I need to sort them in alphabetic order and sometimes by comparing their length.
Initially I used std::set as a container of my data and implemented 2 comparators, hoping that I can change the comparator of the set on the fly, cause the data is huge and it's not a good idea to copy it from one set to another..I just want to sort it using different comparators from time to time. Is this possible or what's the right way to do it?
You have to specify the comparator of std::set
at construction time.
As a solution, I would maintain two 'index' sets instead, each referring to the actual collection. This would yield the greatest flexibility. To keep everything together, I suggest you wrap it up in a single class:
// to be compiled, debugged etc..., but ideal
// to grab the idea
// caveats: maintain the index objects whenever the collection
// gets resized/reallocated etc...
// so not to be written yourself, use an existing library :)
template< typename T, typename comp1, typename comp2 >
struct MultiIndex {
std::deque<T> collection;
std::set<T*, comp1> index1;
std::set<T*, comp2> index2;
void insert( const T& t ){
collection.push_back(t);
index1.insert( &collection.back() );
index2.insert( &collection.back() );
}
};
Boost library has such a class: Multiindex.
The set is internally always kept sorted (otherwise you wouldn't have the needed performance), so no, the comparator can't be changed. What I think the best solution here is to maintain two sets with same data, but with different comparators. I'd encapsulate the two sets in a class and have the functions like insertion work on both sets to ensure the data is the same on both sets.
If you only don't need to have the data sorted all the time, another way to accomplish what you want would be to simply use e.g. a vector and sort by whichever comparator you need when necessary.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With