背景: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;
}
运行结果:
有什么不对的地方欢迎留言讨论
如果觉得有帮助的话点个赞再走,如果能打个赏就更好了,谢谢