C++ map (不影响map结构) 按照 插入顺序排序 (**)

118 篇文章 8 订阅

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值