Effective STL 学习笔记 Item 21:Comparison Function 相关

*/-->

div.org-src-container {
font-size: 85%;
font-family: monospace;
}

1 Always have comparison functions return false for equal values

执行下面的代码:

set<int, less_equal<int> >s; // s is sorted by "<="
s.insert(10); // insert the value 10a.
s.insert(10); // Insert the value 10b again...

第三行会成功么?这里我们使用了 less_equal 作为计算是否 Equivalence 的比较算法,结合前面 对于 Equivalence 的定义,我们可以知道:

\begin{equation}
\left.\begin{matrix}
& !(10_a
最后的结论是先插入的 10 和后插入的 10 不是等价的 (Equivalence) ,最后会导致 10 在这个 set 里面出现两次。

同样的问题即便是在 multiset 里面也存在。 Multiset 确实允许一个元素在 set 里面出现多次,但如调用该容器的 equal_range 方法,该方法会对容器的每个元素调用上面的公式,最后发现相同的值并不等价,从而不能返回完整的 range。

让比较函数在比较等值对象的时候,始终返回 false 则解决了上面的问题,假设:

\(pred(10a, 10b) = pred(10b, 10a) =false\) ,则:

\begin{equation}
\left.\begin{matrix}
& !pred(10_a, 10_b) \\
& !pred(10_b, 10_a)
\end{matrix}\right\}\Rightarrow !false \& !false \Rightarrow true \& true \Rightarrow true
\end{equation}

对于 set 和 multiset,无论是插入还是 equal_range 都没有问题了,记住,给定两个对象,比较函数:
\(pred(a, b)\) 决定了对象 a 是否应该插在对象 b 的前面 。 对象 A 永远不应该插在它自己( 或者其等值对象之前),要永远返回 False 。

2 Strict Weak Ordering

STL 容器中的 \(operator Strict Weak Ordering ,直译为“严格弱排序 ”,名字比较诡异,但其实就是一个受到若干“ 严格 ”约束的 < 操作符,该操作符可以用于集合的排序,形成一个符合
STL 要求的集合。 这些约束条件包括:

  • 反自反性 (irreflexive): 对给定的元素 x,始终满足: \(!(x
    返回去看前面的内容,即要求 \(pred(x, x) = false\) ,要求排序算法对等值对象始终返回 false,其实也正事要求符合反自反性。
  • 非对称性 (asymmetry): 即 $ (x < y)⇒ !(y < x)$
  • 传递性 (Transitivity): \((x
  • 不可比较的传递性: 对于给定的 x, y, z,如果 x 不能和 y 比较,y 不能和 z 比较,则 x 不能和 z 比较。

上面的这个定义不是太好记忆,下面这个衍化版倒是好记:

  • Strict: pred (X, X) is always false.
  • Weak: If !pred (X, Y) && !pred (Y, X), X==Y.
  • Ordering: If pred (X, Y) && pred (Y, Z), then pred (X, Z).

如果不符合上面的规定,则对两个对象执行 Equivalence 判定会出问题, Associative Container 的定义也就不完全。

例如,有个表示屏幕坐标点的类,为其写 \(operator

class Pos
{
public:
Pos(int x, int y)
:m_x(x),
m_y(y)
{}
virtual ~Pos(){}
bool operator< (const Pos& p) const
{
return m_x < p.m_x && m_y < p.m_y;
}
private:
int m_x;
int m_y;
};

上面的 \(operator

正确的写法应该是:

class Pos
{
public:
Pos(int x, int y)
:m_x(x),
m_y(y)
{}
virtual ~Pos(){}
bool operator< (const Pos& p) const
{
if (m_x < p.m_x)
{
return true;
}
else if (m_x > p.m_x)
{
return false;
} if (m_y < p.m_y)
{
return true;
}
else if (m_y > p.m_y)
{
return false;
}
return false;
}
private:
int m_x;
int m_y;
};

Effective STL 学习笔记 Item 21:Comparison Function 相关的更多相关文章

  1. Effective STL 学习笔记 Item 38 : Design functor classes for pass-by-value

    Effective STL 学习笔记 Item 38 : Design functor classes for pass-by-value */--> div.org-src-container ...

  2. Effective STL 学习笔记 Item 34: 了解哪些算法希望输入有序数据

    Effective STL 学习笔记 Item 34: 了解哪些算法希望输入有序数据 */--> div.org-src-container { font-size: 85%; font-fam ...

  3. Effective STL 学习笔记 Item 30: 保证目标区间足够大

    Effective STL 学习笔记 Item 30: 保证目标区间足够大 */--> div.org-src-container { font-size: 85%; font-family: ...

  4. Effective STL 学习笔记 Item 26: Prefer Iterator to reverse_iterator and const_rever_itertor

    Effective STL 学习笔记 Item 26: Prefer Iterator to reverse_iterator and const_rever_itertor */--> div ...

  5. Effective STL 学习笔记 Item 16:vector, string & C API

    有时需要支持 C 的接口,但这并不复杂. 对于 vector 来讲, \(v[0]\) 的地址 \(\&v[0]\) 即可作为数组指针传递给 C API: 1: // Legacy C API ...

  6. Effective STL 学习笔记 Item 18: 慎用 vector<bool>

    vector<bool> 看起来像是一个存放布尔变量的容器,但是其实本身其实并不是一个容器,它里面存放的对象也不是布尔变量,这一点在 GCC 源码中 vector<bool> ...

  7. Effective STL 学习笔记 Item 17: Swap Trick

    假设有若干对象存于一个 vector 中: class Widget; vector<Widget> vw; 后来由于某些原因,从该容器中删除了若干对象(参考erase-remove id ...

  8. Effective STL 学习笔记: Item 22 ~ 24

    Effective STL 学习笔记: Item 22 ~ 24 */--> div.org-src-container { font-size: 85%; font-family: monos ...

  9. Effective STL 学习笔记 32 ~ 33

    Effective STL 学习笔记 32 ~ 33 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...

随机推荐

  1. Python完成RF测试用例

    Robot Framework 框架是基于 Python 语言开发的,所以,它本质上是 Python 的一个库. from robot.api import TestSuite from robot. ...

  2. 【Asp.net入门01】动态网站基础知识

    本节将介绍: 网站搭建流程 动态网站相关基础概念 网页的访问原理 使用浏览器访问网站是我们几乎天天在做的事情.以前我们只需要关注网页内容,作为网站开发人员,从现在开始我们要关注更深层次的东西了. 1. ...

  3. Java入门:绘制简单图形

    在上一节,我们学习了如何使用swing和awt工具创建一个空的窗口,本节学习如何绘制简单图形. 基本绘图介绍 Java中绘制基本图形,可以使用Java类库中的Graphics类,此类位于java.aw ...

  4. 我们使用git checkout 将B分支上的部分页面代码 添加或覆盖到A分支上

    $ git branch * A B $ git checkout B message.html message.css message.js other.js $ git status # On b ...

  5. vue的props和$attrs

    过去我们在vue的父子组件传值的时候,我们先需要的子组件上用props注册一些属性: <template> <div> props:{{name}},{{age}} 或者 {{ ...

  6. Node.js 被分叉出一个项目 — Ayo.js,肿么了

    (注:ayo.js叉从Node.js.目前,大量的文档仍然指向Node.js库.) ayo.js是一个JavaScript运行时建立在Chrome的V8 JavaScript引擎.ayo.js使用事件 ...

  7. 解除单个文件的与svn服务器的关联

    有些文件和个人开发环境有关不需要和svn服务器做同步,可以取消其和svn服务的关联. 右键选中要取消关联的文件,右键菜单 Tortoise SVN  --->   unversion and a ...

  8. 20155307 2016-2017-2 《Java程序设计》第七周学习总结

    学号 2016-2017-2 <Java程序设计>第七周学习总结 教材学习内容总结 认识Lambda语法,方法参考在重用现有API上扮演了重要角色,重用现有方法操作,可避免到处写下Lamb ...

  9. 天梯赛 L2-023. (模拟) 图着色问题

    题目链接 题目描述 图着色问题是一个著名的NP完全问题.给定无向图 G = (V, E),问可否用K种颜色为V中的每一个顶点分配一种颜色,使得不会有两个相邻顶点具有同一种颜色? 但本题并不是要你解决这 ...

  10. HDU 3790 最短路径问题 (最短路)

    题目链接 Problem Description 给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的. ...