当map中key是指针时,我们怎么去find?

情景分析

我们想象这样一种情景,我知道某个人的姓名和电话号码,我们既想要通过这个人的姓名得到到这个人的电话,又想能通过这个人的电话,知道这个人的姓名。

这个时候,我们第一个想到的一定是Map

众所周知,map可以通过调用find函数,通过key索引,迅速访问到value值,在此不在赘述

基础解决方案:

对于上面的问题,我们可以有两种解决方案

  • 第一种,我们可以创建两个map<string, string>,甚至是一个map<string, string>不过保存数据保存两遍,我们传入的值就可以都作为key值来直接调用find函数,这种解决方案,适用于你的数据量比较小,或者对内存没有要求。时间复杂度,和find的时间复杂度一样

  • 第二种,我们可以创建一个map<string, string>,然后判断我们传入的值是key值还是value(也就是姓名还是电话号码),如果是姓名,我们将他作为key值来直接调用find函数,如果是value值,我们可以通过遍历来访问,这样可以节省一些内存,但是牺牲了时间

前面两种方法,都比较简单,但是会造成时间或者空间上的浪费,我们会想,既然能传一个指针,那么可不可以两个都作为指针使用,这样我们同样传两遍,但是传入的数据是指针,可以减少内存的使用,同时又可以调用find函数,也能减少时间复杂度

如果使用两个参数的map,是不可以的,这在大多数人的blog中也可以知道原因,我也不再说明。或者说,你直接试一下就会发现,你的key值如果是一个指针的话,他的地址势必与传入的想要寻找的key值的指针地址不同,永远无法find到

这个时候,我们该如何实现这种骚操作

Map的第三个参数

在官方文档中,map是这样定义的

template < class Key,                                 // map::key_type
           class T,                                   // map::mapped_type
           class Compare = less<Key>,                 // map::key_compare
           class Alloc = allocator<pair<const Key,T> >//map::allocator_type
           > class map;

在此,第一个和第二个参数大家都非常熟悉,我也不再讲解,第四个参数我也还没研究,研究之后我再进行讲解。接下来我们重点来看一下我们今天要用到的第三个参数

查看了map的定义之后,发现map对key的要求就是要定义< operator。为什么map不需要key定义== operator呢?我们觉得,定义< operator用来用来判断两个key的大小,从而决定key在map中排列的次序,而定义==可以用来判断两个key是否相等,从而在使用key引用value的时候用上。

后来查阅了资料,发现定义一个< operator就足够了。当我们使用key来引用value的时候,map采用二分查找法,在map中搜索,如果map找到一个key,发现这个key既不大于我们给的key,也不小于我们给的key,那么,map就认为这两个key相等,从而给出value

熟悉C++的同学,这个时候应该很自然的想到重载,既然我们判断的是key值和传入的值的大小,我们不能直接用STL中定义的< 来比较,那我们是不是可以自己重载运算符,使得我们得以比较我们key值所指向的地址所存的数据,传入的值也是其指向的地址所存的数据,再进行比较,这样就可以实现通过指针来比较

实现方案

struct ptrCmp
{
   bool operator()(const TCHAR *a, const TCHAR *b)
   {
      return _tcscmp(a, b) < 0;
   }
};

typedef map<TCHAR *, TCHAR *, PtrCmp>   TextResMap;

我们只需要通过这样的方式,来实现运算符的重载,调用find函数时,系统会传入两个指针,然后我们比较两个指针所指向的对象,从而实现通过查找

当然,这个时候你需要注意,你在构造map的时候,有两种方式

map<TCHAR *, TCHAR *, PtrCmp> exampleMap或者TextResMap exampleMap

此处TCHAR可以根据你自己想要实现的功能自己定义

综上,如有不足,请指教

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值