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;

  }

}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值