可重复插入?:

set<int ,less_equal<int> >s;
s.insert(10);
s.insert(10);

第二次调用insert,集合回去确认10是否已经存在。因为我们代入的比较函数是 <=

所以集合会检查下面表达式判断是否等价:

!(10a <= 10b) && !(10b <= 10a)

于是会判断出不等价,第二个10就插入成功了。。

至于为什么是这个公式,具体可以参考《STL源码剖析里面》的RB-tree代码:

因为在插入的时候会调用 RB-tree的insert_unique(即避免重复)。然后做出一下判断:

  • 插入点是父亲是最左节点的左儿子:那么直接插入
  • 插入点是普通的左儿子:判断与插入点的祖父点是否相等
  • 插入点是右儿子:直接判断与父亲的关系

假设判断函数‘<’:

  • 最左节点就是值最小的那个点,如果插入点是它左儿子,那么肯定不可能与它相同
  • 如果你是普通左儿子,那么肯定小于父亲节点,而父亲节点 >= 祖父节点,所有当前值有可能与祖父值相同。
  • 如果是右儿子,那么>=父亲节点
  • 对于可能相等的情况判断一下

    于是会先判断 (10b < 10a),因为相等,所以插在右儿子,然后它判断与父亲点的关系

    也就是 (10b > 10a)。如果两个都满足的话,两个点是不相同的。

--

但是判断函数换成了 less_equal( <= ),那么就会有一定的问题,导致相同的也能够插入成功。


元素是指针:

set<string* > v;
v.insert(new string("abc"));
v.insert(new string("bcd"));

如果按照上面的操作,然后将内容按顺序输出,你希望的:

abc bcd

并不一定会出现,因为默认比较函数是比较元素,而set里面保存的是指针。

最后输出的是按照指针大小排序后的结果,所以需要一些处理:

struct StringPtrLess:
public binary_function<const string*,const string*,bool>
{
bool operator()(const string *p1,const string* p2) const
{
return *p1 < *p2;
}
};

自定义比较,然后代入set的声明中

而且因为自定义的比较,可能导致成员函数的find和算法的find出现不同结果。


参考:

Effective STL

STL注意比较函数的更多相关文章

  1. STL传递比较函数进容器的三种方式

    对于STL中的依靠比较排序的容器,均提供了一个模板参数来传递比较函数,默认的为std::less<>. 查阅Containers - C++ Reference可以看到典型的使用比较函数的 ...

  2. 对于一些stl自定义比较函数

    1.unorderd_map自定义键 自定义类型 struct my_key { int num; string name; }; 1.由于unordered_map是采用哈希实现的,对于系统的类型i ...

  3. 各种注意事项(还有c++的一些操作)

    转c++时间: 2017年8月9号 1.记得打头文件 2.=与==的区别(赋值|比较) 3.各种运算符的比较级(与Pascal不同),主要是==与位运算 *4.在OJ上scanf和printf时间优于 ...

  4. STL中sort、priority_queue、map、set的自定义比较函数

    STL中,sort的默认排序为less,也就是说从小到大排序:priority_queue默认是less,也就说大顶堆:map默认是less,也就说用迭代器迭代的时候默认是小的排在前面:set默认是l ...

  5. 详细解说 STL 排序(Sort)

    0 前言: STL,为什么你必须掌握 对于程序员来说,数据结构是必修的一门课.从查找到排序,从链表到二叉树,几乎所有的算法和原理都需要理解,理解不了也要死记硬背下来.幸运的是这些理论都已经比较成熟,算 ...

  6. C++ STL简述

    前言 最近要找工作,免不得要有一番笔试,今年好像突然就都流行在线笔试了,真是搞的我一塌糊涂.有的公司呢,不支持Python,Java我也不会,C有些数据结构又有些复杂,所以是时候把STL再看一遍了-不 ...

  7. STL sort 函数实现详解

    作者:fengcc 原创作品 转载请注明出处 前几天阿里电话一面,被问到STL中sort函数的实现.以前没有仔细探究过,听人说是快速排序,于是回答说用快速排序实现的,但听电话另一端面试官的声音,感觉不 ...

  8. STL~heap

    1.定义 堆:若将此序列所存储的向量R[1..n]看做是一棵完全二叉树的存储结构,则堆实质上是满足如下性质的完全二叉树 树中任一非叶子结点的关键字均不大于(或不小于)其子结点的关键字.分为大根数(默认 ...

  9. STL set 用法

      c++ stl集合set介绍 c++ stl集合(Set)是一种包含已排序对象的关联容器.set/multiset会根据待定的排序准则,自动将元素排序.两者不同在于前者不允许元素重复,而后者允许. ...

随机推荐

  1. Beta开始前准备

    Beta准备 1. 讨论组长是否重选的议题和结论. 经过讨论,我们认为,经过一段时间的磨合,现任组长是不需要更换的. 2. 下一阶段需要改进完善的功能. 增加关于征信的功能,贴近选题主题 美化界面,尽 ...

  2. 20162323周楠《Java程序设计与数据结构》第八周总结

    20162323周楠 2016-2017-2 <程序设计与数据结构>第八周学习总结 教材学习内容总结 一个异常是一个对象,它定义了并不轻易出现的或是错误的情形 异常由程序或运行时环境抛出, ...

  3. 源端控制的OpenFlow数据面

    OpenFlow 交换机一般采用 TCAM 存储和查找流表,从而带来了扩展性.成本和能耗的问题.TCAM 成本和能耗过高,存储容量有限,一般交换机中的 TCAM 仅能存储几千条流表项,对 OpenFl ...

  4. CPP 栈 示例

    #include<iostream> #include<stdlib.h> using namespace std; typedef struct node { int dat ...

  5. python pdb 调试

    命令行 Python -m pdb xxx.py l ----> list 显示当前代码 n ----> next 向下执行一行代码 c ----> continue 继续执行代码 ...

  6. 【iOS】OC-Quartz2D简单使用

    什么是Quartz2D Quartz 2D是一个二维绘图引擎,同时支持iOS和Mac系统 作用 ? 1 2 3 4 5 6 7 8 9 <code>Quartz 2D能完成的工作 绘制图形 ...

  7. Spring Boot jar包linux服务器部署

    Spring Boot 部署 一.使用命令行java -jar 常驻 nohup java -jar spring-boot-1.0-SNAPSHOT.jar > log.file 2>& ...

  8. codves 3044 矩形面积求并

    codves  3044 矩形面积求并  题目等级 : 钻石 Diamond 题目描述 Description 输入n个矩形,求他们总共占地面积(也就是求一下面积的并) 输入描述 Input Desc ...

  9. css精简命名

    想写写前言啥的,发现自己是前言无能星人. 简单吐吐槽好了,来到新公司,接手公司之前的项目,我想着也就是改改bug,慢慢来吧,粗略看了看这个项目的代码,目前仅看了html和css样式的,忍不住吐血三升. ...

  10. EasyUI 主布局整合。

    博文学习地址:http://www.cnblogs.com/xishuai/p/3620327.html html: <%@ Page Language="C#" AutoE ...