Effective STL 学习笔记 Item 21:Comparison Function 相关
Effective STL 学习笔记 Item 21:Comparison Function 相关
*/-->
div.org-src-container {
font-size: 85%;
font-family: monospace;
}
Table of Contents
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;
};
(使用许可:署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议 。)
Effective STL 学习笔记 Item 21:Comparison Function 相关的更多相关文章
- 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 ...
- Effective STL 学习笔记 Item 34: 了解哪些算法希望输入有序数据
Effective STL 学习笔记 Item 34: 了解哪些算法希望输入有序数据 */--> div.org-src-container { font-size: 85%; font-fam ...
- Effective STL 学习笔记 Item 30: 保证目标区间足够大
Effective STL 学习笔记 Item 30: 保证目标区间足够大 */--> div.org-src-container { font-size: 85%; font-family: ...
- 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 ...
- Effective STL 学习笔记 Item 16:vector, string & C API
有时需要支持 C 的接口,但这并不复杂. 对于 vector 来讲, \(v[0]\) 的地址 \(\&v[0]\) 即可作为数组指针传递给 C API: 1: // Legacy C API ...
- Effective STL 学习笔记 Item 18: 慎用 vector<bool>
vector<bool> 看起来像是一个存放布尔变量的容器,但是其实本身其实并不是一个容器,它里面存放的对象也不是布尔变量,这一点在 GCC 源码中 vector<bool> ...
- Effective STL 学习笔记 Item 17: Swap Trick
假设有若干对象存于一个 vector 中: class Widget; vector<Widget> vw; 后来由于某些原因,从该容器中删除了若干对象(参考erase-remove id ...
- Effective STL 学习笔记: Item 22 ~ 24
Effective STL 学习笔记: Item 22 ~ 24 */--> div.org-src-container { font-size: 85%; font-family: monos ...
- Effective STL 学习笔记 32 ~ 33
Effective STL 学习笔记 32 ~ 33 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...
随机推荐
- ES6学习(一)搭建环境
作为一名后端小开发,业务工作需要将后台系统重构一番,许多同事都已经使用前后分离搭建项目,为了不拖后腿自己在家摸索ES6的新特性,真心不知道什么ES3,ES5,一上来就开始搞ES6,在此留下学习笔记,方 ...
- hibernate的懒加载
WHY? WHAT? HOW? 所谓懒加载(lazy)就是延时加载,延迟加载.即不是不加载,而是在需要的时候才加载. 什么时候用懒加载呢,我只能回答要用懒加载的时候就用懒加载. 至于为什么要用懒加载呢 ...
- [转]windows下安装python MySQLdb及问题解决
转自 https://blog.csdn.net/ping523/article/details/54135228#commentBox 之前按照网络上搜罗的教程安装了python-mysql(1.2 ...
- CloseableHttpClient与 CloseableHttpResponse应用
最近在使用Apache的httpclient的时候,maven引用了最新版本4.3,发现Idea提示DefaultHttpClient等常用的类已经不推荐使用了,之前在使用4.2.3版本的时候,还没有 ...
- HIIT训练第一波,值得收藏的训练计划
下面这三套训练,收藏好,平时在家或者出差都能用! 即使你是一个健身新手,也并不意味着高强度间歇训练(HIIT)不适合你. 这种快节奏的训练已经显露出短时间内燃烧成吨卡路里的能力.所以,你并不需要再健身 ...
- session使用
Session的声明与使用 Session的设置不同于Cookie,必须先启动,在PHP中必须调用session_start().session_start()函数的语法格式如下: Bool sess ...
- 2016.6.19——Length of Last Word
Length of Last Word 本题收获: 1.str.size()为负 2.size_t引发的死循环 3.题目思路,有时在写代码时很不清楚边界条件的输出值是什么,若为面试,一定要问清楚. 题 ...
- Oracle Certified Java Programmer 经典题目分析(二)
...接上篇 what is reserved(保留) words in java? A. run B. default C. implement D. import Java 关键字列表 (依字母排 ...
- C# 反射获取和设置值
/// <summary> /// 遍历泛型 /// </summary> /// <typeparam name="T"></typep ...
- ip分片重组 ip_defrag
在ip_local_deliver中,如果检测到是分片包,则需要进行分片重组: ip_local_deliver |-->ip_is_fragment //判断是否为分片包 |-->ip_ ...