【问题标题】:How does STL map know, that map contains a given element?STL 映射如何知道该映射包含给定元素?
【发布时间】:2012-09-08 14:41:11
【问题描述】:

问题Using char as key in stdmap建议使用自定义比较函数/函子:

struct cmp_str
{
   bool operator()(char const *a, char const *b)
   {
      return std::strcmp(a, b) < 0;
   }
};

map<char *, int, cmp_str> BlahBlah;

这允许 map 检测 key A 是否小于 key B。但是例如 ma​​p::find() 返回 end 如果没有找到元素,如果找到则迭代它。所以 map 知道等价,而不仅仅是小于。怎么样?

【问题讨论】:

    标签: c++ stl map


    【解决方案1】:

    ab 两个键的相等条件是 a&lt;bb&lt;a 都是 false。 map 本身通常实现为平衡二叉树*,因此使用小于比较从根节点开始遍历 map,直到找到匹配元素。搜索键 k 时,将使用小于比较,直到找到比较为假的第一个元素。如果反向比较也为假,则k 已找到。否则,k 不在地图中。该地图仅使用小于比较来达到此目的。

    还要注意std::set 使用完全相同的机制,唯一的区别是每个元素都有自己的键。

    * 严格来说,C++ 标准并没有规定std::map 是平衡二叉树,但是它对插入和查找等操作的复杂性约束意味着实现选择了结构比如红黑树。

    【讨论】:

    • @LokiAstari 这就是我在脚注中所说的。
    【解决方案2】:

    等价/operator==可以表示为operator&lt;的函数:

    bool operator==(T left, T right) {
      return !(left < right) && !(right < left);
    }
    

    【讨论】:

    • 是的,虽然std::map 不需要相等运算符,只需要小于比较。
    • @juanchopanza:是的,因为你可以从更少中获得平等。关键是即使不明确,您仍然需要相等性测试。你可以得到质量测试,因为&lt;的要求是严格的弱排序,从而保证你可以使用上述算法进行等价测试。
    【解决方案3】:

    这是因为map的比较器必须实现严格的弱排序,比如&lt;

    这种关系的一个数学属性是Antisymmetry,它表明对于任何xy,那么not (x &lt; y)not (y &lt; x) 意味着x == y

    因此,在找到第一个不比较小于您正在搜索的键的元素后,实现只检查该元素是否比较大,并且它既不小也不大于,那么它必须相等。

    【讨论】:

      猜你喜欢
      • 2011-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-01
      • 2012-02-06
      • 1970-01-01
      • 2019-08-04
      • 1970-01-01
      相关资源
      最近更新 更多