STL映射如何知道,该映射包含一个给定的元素
How does STL map know, that map contains a given element?
有问题的是,在stdmap中使用char作为键,建议使用自定义比较函数/函数:
struct cmp_str
{
bool operator()(char const *a, char const *b)
{
return std::strcmp(a, b) < 0;
}
};
map<char *, int, cmp_str> BlahBlah;
这允许映射检测键A是否小于键B。但例如映射<>:find()如果找不到元素,则返回end,如果找到元素,则迭代器返回。所以map知道等价性,不仅仅是小于。怎样
两个键a
和b
的相等条件是a<b
和b<a
都为false。映射本身通常被实现为平衡二叉树*,因此小于比较用于从根节点遍历映射,直到找到匹配元素。当搜索关键字k
时,使用小于比较,直到找到比较为假的第一个元素为止。如果反向比较也是错误的,则已经找到k
。否则,k
不在映射中。该地图仅使用了小于的比较。
还要注意,std::set
使用完全相同的机制,唯一的区别是每个元素都是它自己的密钥。
*严格来说,C++标准没有规定std::map
是一个平衡的二叉树,但它对插入和查找等操作施加的复杂性限制意味着实现选择了红黑树等结构。
等价/operator==
可以表示为operator<
:的函数
bool operator==(T left, T right) {
return !(left < right) && !(right < left);
}
这是因为映射的比较器必须实现严格的弱排序,例如<
。
这种关系的数学性质之一是反对称性,它指出对于任何x
和y
,那么not (x < y)
和not (y < x)
意味着x == y
。
因此,在找到第一个不比要搜索的键小的元素后,实现只需检查该元素是否比较大,并且既不小也不大,那么它必须相等。
相关文章:
- 如何从存储在std::映射中的std::集中删除元素
- 从嵌套在std::映射中的std::列表中删除元素的最佳方式
- 删除映射和分割错误中的一个过去结束元素
- 为什么在 std::map 上移动无法将元素从一个映射移动到另一个映射
- 访问映射向量的映射元素(c++)
- 为什么 unordered_map::equal_range upper_bound 如果键小于第一个映射元素,则返回
- 根据类成员对同一密钥的多映射元素进行排序
- C++查找并擦除多映射元素
- C++ for_each循环找不到指向映射元素
- 创建映射元素时,请避免使用值副本
- 从常量迭代器到映射向量,获取映射向量中映射元素的键和值
- c++中如何更改映射元素的值
- 传递对映射元素的引用作为参数
- 如果没有找到映射元素将返回什么
- 不能访问指针-向量映射元素
- 存储内部排序映射元素的最快方式
- 无序多映射元素插入
- 哈希映射元素的值未正确打印
- 修改所有映射元素的键
- 复制映射元素的正确方法