STL std :: map动态排序

时间:2010-12-16 05:22:55

标签: c++

我知道这可能是一个愚蠢的问题。但我很困惑。 W.r.t std :: map。我为地图的动态排序编写了一个自定义谓词,

enum OrderingType 
{
    ASCENDING, 
    DESCENDING 
};

template <class T>
class Ordering
{
    OrderingType m_order;

public:
    Ordering(OrderingType order) : m_order(order) { }

    bool operator() (const T &obj1, const T &obj2)
    {
        if( m_order == ASCENDING )
            return obj1 < obj2;

        if( m_order == DESCENDING )
            return obj1 > obj2;
    } 
};

优势是

  1. 我们可以在某些条件下决定地图中数据元素的排序

    OrderType type =(condition?ASCENDING:DESCENDING);    CUSTOMMAP m(类型);

  2. 对于升序和升序,我们可以使用相同的前向迭代器降序有序地图

    在下面的代码中。地图的排序在升序和升序中都很好。降序(amp1&amp; map2)。但是在赋值map2 = map1时,map2的顺序随内容一起变化。我被期望只复制内容,而不是订单的变化。 map2上的进一步插入(声明为降序)将按升序排列。

  3. 任何建议或想法......?或者为地图定义双向排序谓词是个坏主意..?

    typedef map<int, int, Ordering<int> >  CUSTOMMAP;
    typedef CUSTOMMAP::iterator       CUSTOMMAP_ITER;
    typedef CUSTOMMAP::const_iterator CUSTOMMAP_CONST_ITER;
    
    ostream& operator <<(ostream& out, const CUSTOMMAP& mapobj)
    {
        CUSTOMMAP_CONST_ITER citer = mapobj.begin();
        for( ; citer != mapobj.end(); ++citer )
        {
            out << citer->first << "   " << citer->second << endl;
        } 
        out << "==========" << endl;
        return out;
    }
    
    int main()
    {
        CUSTOMMAP map1(ASCENDING);     //instantiate a map with ascending sorting
        CUSTOMMAP map2(DESCENDING);    //instantiate a map with descending sorting
    
        map1.insert( make_pair(1, 0));
        map1.insert( make_pair(2, 0));
        cout << map1;                  // prints data in ascnding manner 
    
        map2.insert( make_pair(5, 0));
        map2.insert( make_pair(6, 0));
        cout << map2;                  // prints data in descending manner 
    
        map2 = map1;
    
        cout << map2;                  //copys contents of map1 to map2 & changes 
                                       //map2's ordering predicate
        return 0;
    }
    

2 个答案:

答案 0 :(得分:5)

设置好map2 = map1实际上会复制整个对象,而不仅仅是元素。您可能想要做的是

map2.clear();
map2.insert(map1.begin(), map1.end());

我完全相信两个步骤的复杂性将是O(n log n),但不要引用我。

修改

更好(O(n)):

map2.clear();
map2.insert(map1.rbegin(), map1.rend());

“对于第三个版本(插入(第一个,最后一个)),一般是Nlog(大小+ N)(其中N是第一个和最后一个之间的距离,并且在插入之前调整容器的大小),但是线性的如果第一个和最后一个之间的元素已经按照容器使用的相同排序标准进行了排序。“ (http://cplusplus.com/reference/stl/map/insert)

答案 1 :(得分:0)

比较器对象(不仅仅是类型)成为地图的成员。在赋值时,复制元素和比较器。这就是为什么map2获得与map1相同的顺序。

要复制元素,您可以使用map2.insert(map1.begin(), map1.end())