统计map中key小于某类型变量的个数

本文介绍了使用STL容器中的map进行元素计数的三种方法,包括遍历计数、利用count_if算法以及结合bind2nd仿函数进行高效计数,并深入探讨了不同方法之间的差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

map的成员函数没有提供这一功能,对于这个问题,我首先想到的方法是,循环遍历一下,将其中每个元素和比较对象进行比较,就可以了,代码如下(为了方便说明,我将key的类型定义为int,对于其他类型的或是自定义类型的,可能需要自己写比较函数)

 1 map<intint>testMap;
 2 
 3 for (int i = 1; i < 11++i)
 4 {
 5    testMap.insert(make_pair(i, i+100));
 6 }
 7 
 8 int nCount = 0;
 9 for (itor = testMap.begin(); itor != testMap.end(); ++itor)
10 {
11    if (itor->first < 5)
12    {
13      ++nCount;
14    }
15 }


但是,在网上常看到很多高手都会给我们这样的忠告,在处理STL容器的时候,尽量不要自己去写循环处理。
在STL中,count_if这个算法,正符合我们的要求,而我们只需要提供比较函数就可以了,代码如下:

 1 template<class key, class Value>
 2 class cmp_less
 3 {
 4 public:
 5     cmp_less(key K)
 6         :nKey(K)
 7     {
 8 
 9     }
10 
11     bool operator()(pair<key, Value> elems)
12     {
13         if (elems.first < nKey)
14         {
15             return true;
16         }
17         else
18         {
19             return false;
20         }
21     }
22 private:
23     key nKey;
24 };
25 
26 nCount = count_if(testMap.begin(), testMap.end(), cmp_less<intint>(5));

文章写到这里也能结束了,但这几天在看bind2nd这个仿函数和别人文章的时候,想改用bind2nd试试,也看看自己掌握的情况,不用不知道,在写代码的时候才发现自己掌握的比较肤浅,尝试了大半天,侯捷老师的STL源码剖析一书也翻了好几次,总算写出来,代码如下:

 1 template<class Key, class Value>
 2 class myless : public binary_function<pair<Key, Value>, Key, bool>
 3 {
 4 public:
 5     bool operator()(pair<Key, Value> elemnt, Key other) const
 6     {
 7         if (elemnt.first < other)
 8         {
 9             return true;
10         }
11         else
12         {
13             return false;
14         }
15     }
16 };
17 
18 nCount = count_if(testMap.begin(), testMap.end(), bind2nd(myless<intint>(), 5));

在这之前我写出了这样的代码,

1 nCount = count_if(testMap.begin(), testMap.end(), bind2nd(less<pair<intint>>(), make_pair(5100)));

这样也可以比较,但有个问题,因为这样写是两个pair比较,而pair比较是这样的,请看源代码:

1 template<class _Ty1, class _Ty2> 
2 inline bool operator<(const pair<_Ty1, _Ty2>& _Left, const pair<_Ty1, _Ty2>& _Right)
3 {    // test if _Left < _Right for pairs
4    return (_Left.first < _Right.first ||
5            !(_Right.first < _Left.first) && _Left.second < _Right.second);
6 }

不仅比较key,还要比较value,这样必须把右边pair的value的值设的够大才行,这不符合我们要求,我们只要求key做比较。
bind2nd源代码是这样的,请看:

1 template<class _Fn2, class _Ty>
2 inline binder2nd<_Fn2> bind2nd(const _Fn2& _Func, const _Ty& _Right)
3 {    // return a binder2nd functor adapter
4    typename _Fn2::second_argument_type _Val(_Right);
5    return (std::binder2nd<_Fn2>(_Func, _Val));
6 }

我们注意到这句代码typename _Fn2::second_argument_type _Val(_Right);
就是右边的值(即做比较的值)要能向_Fn2::second_argument_type转换,而且是由_Fn2提供的,_Fn2::second_argument_type是什么呢,请看

1 template<class _Arg1, class _Arg2, class _Result>
2 struct binary_function
3 {    // base class for binary functions
4     typedef _Arg1 first_argument_type;
5     typedef _Arg2 second_argument_type;
6     typedef _Result result_type;
7 };

first_argument_type是左边参数类型,second_argument_type是右边参数类型,由于是map左边是pair,右边我们要求是key的类型,即int,所以我们
的定义这样的

1 template<class Key, class Value>
2 class myless : public binary_function<pair<Key, Value>, Key, bool>
3 



就这三个方法,个人感觉还是第二个比较好。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值