背景:key-value形式的数据,已经使用了map存储,后来要求读取时的顺序要和插入的顺序一致

  方案一、再定义个数组,按顺序保存key (推荐)

  方案二、map更换为unordered_map (经验证,此方案不可行)

  方案三、禁止map自动排序 (map.find方法不可用,插入时不能使用insert)

其实正常来说方案一应该是最好的选择,但由于方案一的改动量比较大,本人又比较懒(主要原因),而且场景也很特殊,并没有用到map.find方法

所以先选择了方案二,以前知道unordered_map是无序的,但一直没什么机会用,现在用起来才发现unordered_map真的是无序的......连插入的顺序都保证不了,在没研究底层哈希结构的前提下,完全就是乱序的

所以,方案二Pass

方案三,知道map容器的第三个参数是排序相关的(降序的时候用过),所以需要自己实现一个排序相关的函数

在网上查了很多资料,大部是直接返回true或者加了相等的判断,不知道为什么我试了都不行

有说这种方法只适用key是int的情况,我也试了,不行....(可能是人品吧)

后来才知道

    map如果想第三个参数返回true需要经过两次比较,如果第一次返回true那么会把左右参数对调再判断一次,这一次则要返回false,才能无序排列(摘自https://blog.csdn.net/sendinn/article/details/96286849,我简单测了一下好像不止两次,但方法是没问题的,就不再深究了)

代码如下:

#include <stdlib.h>
#include <iostream>
#include <map>

using namespace std;


//T如果不是基本类型,需要==运算符重载
template<typename T>
struct DisableCompare : public std::binary_function<T, T, bool>
{
    bool operator()(T lhs, T rhs) const
    {
        static T l = lhs;
        static T r = rhs;

        if(lhs == rhs)
        {
            return false;
        }

        if(l == rhs && r == lhs)
        {
            l = lhs;
            r = rhs;
            return false;
        }

        l = lhs;
        r = rhs;
        return true;
    }

/*经测试此方法数据超过5个就不行了
    bool operator()(T lhs, T rhs) const
    {
        static bool s_bFlag = false;

        if(lhs == rhs)
        {
            return false;
        }

        if(s_bFlag)
        {
            s_bFlag = false;
        }
        else
        {
            s_bFlag = true;
        }

        return s_bFlag;
    }
*/
};

int main(int argc, char *argv[])
{
    map<int, string> mapTest1; //正常排序
    mapTest1.insert(make_pair(1, "a")); //可以用insert
    mapTest1.insert(make_pair(4, "a"));
    mapTest1.insert(make_pair(3, "a"));
    mapTest1.insert(make_pair(2, "a"));

    cout << "map<int, string>" << endl;

    //map<int, string>::iterator iterTest1 = mapTest1.begin();
    auto iterTest1 = mapTest1.begin();
    while(mapTest1.end() != iterTest1)
    {
        cout << iterTest1->first << ": " << iterTest1->second << endl;
        iterTest1++;
    }

    map<int, string, DisableCompare<int> > mapTest2; //不排序
//    mapTest2.insert(make_pair("1", "a")); //不可以用insert
//    mapTest2.insert(make_pair("4", "a"));
//    mapTest2.insert(make_pair("3", "a"));
//    mapTest2.insert(make_pair("2", "a"));
    mapTest2[1] = "a";
    mapTest2[4] = "a";
    mapTest2[3] = "a";
    mapTest2[2] = "a";

    cout << "map<int, string, DisableCompare<int> >" << endl;

    //map<int, string, DisableCompare<int> >::iterator iterTest2 = mapTest1.begin();
    auto iterTest2 = mapTest2.begin();
    while(mapTest2.end() != iterTest2)
    {
        cout << iterTest2->first << ": " << iterTest2->second << endl;
        iterTest2++;
    }

    system("pause");

    return 0;
}

运行结果:

有什么不对的地方欢迎留言讨论

如果觉得有帮助的话点个赞再走,如果能打个赏就更好了,谢谢

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐