C++ map (不影响map结构) 按照 插入顺序排序
C++实现的支持插入顺序的高效map (第三方的库 ??)
-----------------------------------------------------
要点:
1. Qt 设计的初期,只是一个自成系统的图形框架,它的功能只是为了满足设计 ui之用。
虽然后来不断地扩大了使用的范围,使其有向 全功能的 C++靠拢的趋势;但是,只是趋势而已,而不是取代;这意味着 C++的许多功能和特性,Qt 可能是没有的。
复杂的实现,还得从 C++入手。比如:unordered_map。
2. map设计的意义就是用来排序,加快查询速度的。
3. 将 真实key放到值位,使用 int作为 map的值,这样虽然可以按照插入排序,但是,无法保证 真实key的唯一性。
------------------------------------------------------
boost::unorder_map如何插入元素_链表和有序二叉树插入元素时真的比数组快吗?
boost::unorder_map如何插入元素_链表和有序二叉树插入元素时真的比数组快吗?_weixin_39517902的博客-CSDN博客
===============================
C++实现的支持插入顺序的高效map
https://blog.csdn.net/v6543210/article/details/83016798
https://github.com/nlohmann/fifo_map
C++ map (不影响map结构) 按照 插入顺序排序
我用的是qt,但是这里用的方法qmap却不支持,挺郁闷的。
看到java有现成的 linkedhashmap使用,更郁闷。
做项目的时候,从数据库搜索了几万条数据,需要对每条数据处理,然后把处理结果显示。开始用的qmap,map的键值对是地址-其他信息,很快捷方便。但是看显示结果的时候发现,qmap自动排序了,我显示的有时间,但是这里却把地址排序。所以我想实现按照时间排序。
一开始的思路是对qmap或map本身动手脚,但是各处搜索,发现几个思路。
1. 重载map的构造函数的第三个参数,有人干脆直接永远返回true。这样的弊端一个是让map快速查询变得没了意义,甚至会在find等调用到比较函数的地方出现错误。先舍弃。
2. 有人说用List<pair<string,T> >链表,但是链表本身并不排序,我自己试了一下,本来用map是300~500ms就把数据库查询的数据处理完毕了,用来这种结构时间变成了8s。我不觉得我的用户会有耐心等那么久。
翻看论坛评论的时候,无意看到一个评论让我醍醐灌顶,map设计的意义就是用来排序,加快查询速度的,何必舍本逐末。我所苦苦追求的,对map改动不现实,当你按照插入顺序排序之后,势必改动了map本身的排序算法,那么我这几万条查询数据岂不是又变成8s多!但是如果我把map所有数据拿到之后,想办法按值排序呢!
思路:
1、构造multimap,multimap<QString,ASSOCReqAddrsResult> assocReqAddrListResult;其value是个结构体,在结构体中增加index变量,用于之后的比较。
2、填充map,填充时记得按照增加的顺序把值赋值给index
3、将一对多的map放到vecor容器,vec等容器支持sort或qsort进行自定义比较算法
4、直接调用sort,对map按index排序,即可实现想要的效果。
前面两步十分简单,重点说第三、四步。
map->vector容器:
//把map中元素转存到vector中
vector<SPAIR> vec(assocReqAddrListResult.begin(),assocReqAddrListResult.end());
sort的构造函数如下:
template <class RandomAccessIterator>
void sort ( RandomAccessIterator first, RandomAccessIterator last );
template <class RandomAccessIterator, class Compare>
void sort ( RandomAccessIterator first, RandomAccessIterator last, Compare comp );
qt中有qsort构造函数(ps:帮助索引qsort有个简单的例子)
void qSort(RandomAccessIterator begin, RandomAccessIterator end, LessThan lessThan)
都是一个意思,可以对第三个参数传入一个函数地址,实现自定义排序。我的例子如下:
bool cmp(const SPAIR& x,const SPAIR& y){
return x.second.index<y.second.index;
}
这里的vec里的元素是SPAIR,所以我们这里这里的比较对象,应该比较的也是SPAIR。
最后直接调用即可:
sort(vec.begin(),vec.end(),cmp);
测试代码如下:
#include <iostream>
#include "vector"
#include <map>
#include <Qdebug>
#include <algorithm>
class ASSOCReqAddrsResult{
public:
unsigned index;
QString recvTime;//时间
...
bool operator <(ASSOCReqAddrsResult item){return index<item.index;}
};
typedef pair<QString,ASSOCReqAddrsResult> SPAIR;
bool cmp(const SPAIR& x,const SPAIR& y){
return x.second.index<y.second.index;
}
int main(){
multimap<QString,ASSOCReqAddrsResult> assocReqAddrListResult;
ASSOCReqAddrsResult item;
item.index = 0;
item.recvTime = "08:20:22.123";
assocReqAddrListResult.insert(make_pair("11",item));
item.index = 1;
item.recvTime = "08:20:26.124";
assocReqAddrListResult.insert(make_pair("01",item));
item.index = 2;
item.recvTime = "08:20:32.125";
assocReqAddrListResult.insert(make_pair("31",item));
//把map中元素转存到vector中
vector<SPAIR> vec(assocReqAddrListResult.begin(),assocReqAddrListResult.end());
sort(vec.begin(),vec.end(),cmp);
for(int i=0;i<vec.size();i++){
qdebug()<<vec[i].second.recvTime<<","<<vec[i].second.index<<","<<vec[i].first;
}
}
————————————————
版权声明:本文为CSDN博主「违规昵称9527」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_38431416/article/details/107867647