如果比较器需要严格的总排序而不是严格的弱排序,C++ 标准算法会更快吗?

Mat*_* K. 6 c++ algorithm std comparator

许多 C++ 标准算法,例如std::sort(),假设比较器comp严格的弱排序,并且不能假设它comp具有任何其他(好的)属性。但很多时候comp确实有更多的属性,而不仅仅是严格的弱排序。特别是, many timescomp严格的全序(因此,特别是,对于所有ab: comp(a, b)comp(b, a)、 或,以下条件之一始终为真a = b)。例如,通常operator<()的浮点数、整数和std::strings 都是严格的全序。

通过将自身限制为假设这comp是一个严格的弱排序,C++ 标准库是否将自身限制为使用非最佳算法?换句话说,如果 C++ 标准算法假设比较器是严格的总排序而不是严格的弱排序,那么某些标准算法会比当前实现的算法更快吗?

更新:更确切的什么“严总序”的意思,让我们假设STL假设comp(对类型的对象操作T)把所有的美好秩序论的属性,这些属性operator<()intS有。(因此,如果您愿意,我们还可以假设operator==()在类型对象上也有一个T按您预期工作的定义;这个假设是可选的,如果您愿意,您可以做出不同的假设。)任何 STL 算法都可以吗?做得更快?

更一般地说,如果 STL 做出了“更好”的假设comp(即假设comp不仅仅是严格的弱排序),那么任何 STL 算法都可以做得更快吗?

cur*_*guy 1

例如,常见的operator<()浮点数、整数、 和 std::strings都是严格的全序。

所以你只是在谈论状态的相似性,而不是真正的平等(无论在具有可变状态的语言中是什么)。

通过将自身限制为仅假设 comp 是严格的弱排序,C++ 标准库是否限制了自身

不,前提是错误的。根据定义,容器和算法库(生成排序序列的算法、在排序范围上操作的算法以及有序关联容器)并不任何方式限制自身:它明确表示等价关系,据我所知, 't 命名(我们称之为Sim)可以根据比较 Comp 来定义:

Sim (x,y) <=> !Comp(x,y) && !Comp(y,x)

所以你有严格的顺序,只需将 Sim 称为“相等”并将重载operator==定义为Sim

因此,唯一的问题是使用二进制比较函数的愚蠢之处,这意味着对 f.ex 进行多次扫描。字符串来确定相等性,并且无法访问三元比较(例如strcmp)。如果您可以直接访问Sim ,那么在相等的情况下您仍然会调用Comp而不是Sim ,或者选择Comp然后调用另一个Comp

仅当您先验怀疑“相等”是最可能的结果时,您才会使用Sim然后使用Comp。这是荒谬的。

三种方法更适合比较序列。走三路。