Is it possible to change the comparator of a C++ std::set?

你离开我真会死。 提交于 2019-12-10 14:48:13

问题


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?


回答1:


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.




回答2:


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.




回答3:


No, not on the fly. The tree is built based on the sort criteria specified at construction time. You are talking about building multiple indexes into a single dataset, which could be accomplished with multiple sets. There are probably lots of libs like boost which have something already created for this.



来源:https://stackoverflow.com/questions/7777827/is-it-possible-to-change-the-comparator-of-a-c-stdset

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!