下面的比较器函数如何在c ++中工作?

时间:2018-05-30 06:14:27

标签: c++

bool comp(int a,int b){

    if ((a > 0 && b > 0) || (a < 0 && b < 0))
        return false;

    if ((a > 0) && (b < 0))
        return false;
}

对于包含正整数和负整数的给定数组,上述函数可用于重新排列数组,使得负整数后跟正整数,并保留元素的顺序。

示例:

int arr [] = {1,2,-3,-1}, n=sizeof(arr)/sizeof(int);

sort(arr,arr+n, comp);

output : {-3,-1,1,2}

但是我无法理解它是如何工作的,有人可以解释一下吗?

2 个答案:

答案 0 :(得分:7)

你的断言在两个方面是错误的:

  1. std::sort 保证保留不需要排序的元素的顺序,如果你理解了我的意思。

  2. comp函数的行为未定义,因为它在所有控制路径上都没有明确的return值。

  3. 一种补救措施是使用std::stable_sort,它将尽可能地保留元素的顺序。如果第一个参数为负且第二个参数为正(让我们将0定义为正),则可以调整比较器函数,使其为true

    bool comp(int a, int b){
        return a < 0 && b >= 0;
    }
    

    另一种补救措施是使用std::stable_partition

答案 1 :(得分:0)

  

但是我无法理解它是如何工作的,有人可以解释一下吗?

我尝试解释它应该如何工作,但实际上,它不起作用:)

bool comp(int a, int b) {

    if((a > 0 && b > 0) || (a < 0 && b < 0))
        return false;

    if((a > 0) && (b < 0))
        return false;

    return true;
}

此代码尝试比较符号:检查a的符号是否“小于”b的符号。假设负面“少于”正面。因此,-1的符号小于1的符号,-3的符号不小于-1的符号。

这里的问题是比较器应始终符合https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings

简而言之,严格的弱排序是:对于任何ab,只有一个条件为真:a < bb < ab == a 。当一个条件更多时,情况就不应该存在。

当生产代码中违反了严格的弱排序时,会发生非常糟糕的事情:加班,失败的最后期限,甚至更糟。

您的sort()将在此数组上失败:{ 1, 0, 2, 0, -3, 0,-1 }因为违反了严格的弱排序:comp(-1, 0)为真且comp(0, -1)为真。