是否可以更改C ++ std :: set的比较器?

时间:2011-10-15 12:29:14

标签: c++ set comparator

我有一组数据,在某些情况下我需要以某种方式对它们进行排序,有些情况则以另一种方式对它们进行排序。例如,假设数据集是一组字符串,{" abc"," dfg",...}。有时我需要按字母顺序对它们进行排序,有时候还要比较它们的长度。

最初我使用std :: set作为我的数据的容器并实现了2个比较器,希望我可以动态更改集合的比较器,因为数据很大并且它不是个好主意将它从一个集合复制到另一个集合......我只是想不时使用不同的比较器对它进行排序。这是可能的,或者是正确的方法吗?

3 个答案:

答案 0 :(得分:6)

您必须在施工时指定std::set的比较器。

作为一个解决方案,我会维护两个'索引'集,每个集都指实际的集合。这将产生最大的灵活性。为了将所有内容保持在一起,我建议你把它整理成一个类:

// 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库有这样一个类:Multiindex

答案 1 :(得分:2)

该组在内部始终保持排序(否则您将无法获得所需的性能),因此,不能更改比较器。我认为这里最好的解决方案是使用相同的数据维护两组,但使用不同的比较器。我将这两个集合封装在一个类中,并在两个集合上都具有插入工作等功能,以确保两个集合上的数据相同。

如果您不需要始终对数据进行排序,那么另一种实现您想要的方法就是简单地使用例如一个向量,并在必要时用你需要的比较器进行排序。

答案 2 :(得分:1)

不,不是在飞行中。树是根据构造时指定的排序条件构建的。您正在讨论将多个索引构建到单个数据集中,这可以通过多个集合来完成。可能有许多类似于boost的库已经为此创建了一些东西。