地图计数确实很重要,或者只是检查是否存在

Map count really counts or just checks existence

本文关键字:或者 检查 存在 是否 地图      更新时间:2023-10-16

在CPP入门或其他网站上,我发现count(来自STLmap(定义的语言非常模糊和误导:

在容器中搜索键等效于 k 的元素,并返回匹配项数

到目前为止,我所研究的是key是奇异的,映射值也是奇异的 - 映射值可以通过赋值来更改。

那么它不只返回容器是否包含密钥吗?而不是伯爵?我在理解这个概念时哪里错了?

std::map

count(( 将始终返回 0 或 1。

但是C++库还有其他关联容器,这些容器很可能具有同一键的多个值。喜欢std::multimapstd::multiset.幸运的是,他们还有一个count()方法,实际上可能返回大于 1 的值。

但这允许您做的是通过开发可以使用任何关联容器的模板进行元编程,这些模板可能是唯一的,也可能不是唯一的。您的模板需要做的就是使用count()来确定具有给定键的容器中存在多少个值,最终结果可以与std::mapstd::multimap一起使用。它丝毫不会在乎。在这两种情况下,您的模板都将获得正确的答案:具有给定键的容器中的值数。

根据 cplusplus.com

由于映射容器中的所有元素都是唯一的,因此该函数只能返回 1(如果找到元素(或零(否则(。

虽然前面的答案在count重载方面是正确的,但这需要类型std::map::key_type的参数,它们没有解决另一个需要模板化键的重载:

template< class K > 
size_type count( const K& x ) const;

如此处所述,此重载"返回与 key 比较等效值 x 的元素数"。 这可以通过使用定义与自定义类型进行比较的自定义比较器返回大于 1 的值。

在下面的示例中,我编写了一个比较器,用于定义结构StartsWithK的比较。这允许我将结构的实例作为键传递。


#include <map>
#include <string>
#include <iostream>
// Type for key argument
struct StartsWithK {};
// Custom comparator
struct Comp{
using is_transparent = void;
bool operator()(std::string lhs, std::string rhs) const {
return lhs.compare(rhs) < 0;
}
bool operator()(std::string lhs, StartsWithK rhs) const {
return tolower(lhs[0]) < 'k';
}
bool operator()(StartsWithK lhs, std::string rhs) const {
return 'k' < tolower(rhs[0]);
}
};
int main() {
// Pass custom comparator as template argument
typedef std::map<std::string,bool,Comp> IntMap;
IntMap map;
// Some dummy entries, note that there are four keys that start with k
map.emplace("army",true);
map.emplace("knight",true);
map.emplace("key",true);
map.emplace("kilogram",true);
map.emplace("robot",true);
map.emplace("karma",true);
map.emplace("sale",true);
// Display the results of std::map::equal_range and std::map::count
IntMap::const_iterator it1;
IntMap::const_iterator it2;
std::tie(it1,it2) = map.equal_range(StartsWithK());
std::cout << it1->first << " " << it2->first << std::endl;
std::cout << map.count(StartsWithK()) << std::endl;
}

控制台输出为:

karma robot
4

我已经尝试过这个,我发现如下:

  1. 匹配的键必须直接按照std::map的键顺序相互跟随
  2. 匹配键
  3. 前面的键必须低于匹配键
  4. 匹配键
  5. 后面的键必须大于匹配键的比较

换句话说,上面的示例之所以有效,是因为所有以字母 k 开头的键都已经按顺序排列,因为std::map按字母顺序对其键进行排序。相反,我尝试实现一个带有int键的映射,使用count来查找偶数键的数量,但这不起作用,因为奇数和偶数交替出现。

我对幕后发生的事情的猜测是,std::map在内部运行lower_bound(key)upper_bound(key),然后返回返回迭代器之间的距离作为结果。从我的测试中,我可以判断出count不会单独检查每个键的等效性。

我还没有在网上找到任何使用自定义比较器的示例,而且文档很少,可能是错误的。