【问题标题】:C++ std::sort custom comparator runs indefinitely when the comparator returns true当比较器返回 true 时,C++ std::sort 自定义比较器无限期运行
【发布时间】:2021-01-11 17:40:04
【问题描述】:

因此,在使用自定义比较器对向量进行排序时,我在边缘情况下遇到了这种非常奇怪的行为。

运行此代码时,它不会停止,而是永远运行:

int main() {
    auto comp = [](int lhs, int rhs) {
        return true;
    };
    
    vector<int> vec{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    sort(vec.begin(), vec.end(), comp);
    
    for (int num : vec)
        cout << num;
    
    return 0;
}

但是,当我将 true 更改为 false 时,它可以完美运行。

auto comp = [](int lhs, int rhs) {
    return false;
};

更奇怪的是,当我减少要排序的0 的数量时,它也能正常工作。 (它适用于16个或更少的0,当我再添加一个0使其成为17时,程序不会再次停止。(如果长度超过16,g++会切换到另一种排序算法吗?)

vector<int> vec{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

为什么会这样?我是否遗漏了 C++ 的 sort() 函数中的一些重要概念?

【问题讨论】:

  • 你的比较器没有实现严格的弱排序 -> 未定义的行为
  • “如果长度超过 16,g++ 会切换到另一种排序算法吗?” 这是合法的,事实上,编译器倾向于使用混合算法来提高性能,保证复杂性.

标签: c++ sorting stl strict-weak-ordering


【解决方案1】:

这个比较器:

auto comp = [](int lhs, int rhs) {
   return true;
};

违反了std::sort 比较器必须建立严格-弱排序的要求。请注意,无论参数的顺序如何,此函数都会返回true,这意味着两个元素都可以小于另一个,这实际上没有意义。违反std::sort 的这一要求会调用未定义的行为(这足以解释您在不同的vector 大小下看到的不同行为)。


另一方面,这个比较器:

auto comp = [](int lhs, int rhs) {
    return false;
};

完全没问题。它基本上说没有元素比任何其他元素都少(即它们都是等价的)。这满足 strict-weak-ordering,所以 std::sort 可以正常工作。

当然,std::sort 不会对第二个比较器做任何有用的事情,因为所有元素都已经“排序”了。不过,这可能会重新排序元素;但如果你使用std::stable_sort 则保证原始范围不变。

【讨论】:

  • 你已经有我的投票了。我不确定是否要关闭,但这个答案确实增加了一些东西
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多