int comp(int *x, int *y){
return *x - *y;
}
std::sort()
的比较函数看起来更加一致,因为它是根据遵循不变式的函数编写的。即如果x小于y,则函数返回true,x相对于y处于正确的位置。
bool comp(int x, int y){
return x < y;
}
为什么在返回布尔值(或只有0、1两个值的整数)时,我们需要使用三个值-1、0、+1,而不是更简单和清晰的方式?
int comp(int *x, int *y){
return *x - *y;
}
std::sort()
的比较函数看起来更加一致,因为它是根据遵循不变式的函数编写的。即如果x小于y,则函数返回true,x相对于y处于正确的位置。
bool comp(int x, int y){
return x < y;
}
为什么在返回布尔值(或只有0、1两个值的整数)时,我们需要使用三个值-1、0、+1,而不是更简单和清晰的方式?
其他人指出了两种比较方式的等效性,以下是为什么采用这两种方法的原因。
在C语言中,比较需要一个函数指针。这意味着您始终会得到函数调用和指针间接的开销。当qsort
在1970年代设计时,它运行在一台PDP-11计算机上,必须减少开销,所以比较函数(如strcmp
)需要在单个函数调用中进行三向比较。(请注意,qsort
通常是不稳定的排序,因此相等情况可能看起来无用,但可以通过适当的指针比较使其稳定。)
在C ++中,比较可以在模板实例化时进行内联,因此大部分开销消失了(甚至不需要函数调用),可以使用更简单的约定。这也意味着std::sort
默认可以使用operator<
重载工作。
我曾经也思考过同样的问题,并且提出了一个基于strcmp
和std::string::compare
的理论。也就是说,做比较可能需要相对较长的时间。为了确定一个对象A
是否小于、等于或大于另一个对象B
,可以使用如下代码:
if (A < B) {
//do stuff where A is less
} else if (B < A) {
//do stuff where A is greater
} else {
//do stuff where A is equal
}
if (A < B) {
//do stuff where A is less
} else {
//do stuff where A is greater or equal
}
string::operator<
比strcmp
快近一倍,调用string::operator<
两次仅比调用一次稍慢。(我猜测是因为缓存和更简单的代码?) GCC的结果也类似。volatile
。 - Jim Balter!(x < y) && !(y < x)
并不总是等同于x == y
,尽管对于所有常见情况都是如此。这完全取决于您如何定义 <
和 ==
运算符。 - Mark Ransomcmp
更有效率,特别是对于 std::map/std::set
这样的东西,因为它们会多次应用 std::less/operator<
,而只需一次调用 cmp
就足够了。 - Maxim Egorushkinqsort比较函数的模型是基于strcmp和memcmp的,它们返回<0、0或>0,这比仅返回<或>=指示符更具信息性……需要进行两次这样的调用才能确定两个元素是否相等。这里不适用“不变量”的概念:显然,a [i]<a [i + 1]的不变量不适用于原始数组……实际上,对于最终数组,它也不适用,因为a [i] == a [i + 1]是可能的。术语“一致”也不适用……结果必须对两种类型的比较函数都一致且必须如此。“更干净”的问题在于观察者,而使用“简单得多”则言过其实。
std::sort
;如果你在使用C进行编程,则请使用qsort
。此外,有些C++容器不能使用qsort
进行排序,因此你别无选择。 - Some programmer dudecomp
后区分x > y
vsx == y
vsx < y
(在第一种情况下)。 - Drew McGowen*x - *y
是错误的,例如如果*x == INT_MAX
且*y == INT_MIN
。 - Cubbi