std::sort 总是比较相等的值吗?

Posted

技术标签:

【中文标题】std::sort 总是比较相等的值吗?【英文标题】:Will std::sort always compare equal values? 【发布时间】:2022-01-05 05:36:36 【问题描述】:

我在 leetcode 上做如下问题:https://leetcode.com/problems/contains-duplicate/

给定一个整数数组 nums,如果至少出现任何值,则返回 true 数组中的两次,如果每个元素都是不同的,则返回 false。

我提出的问题的解决方案如下:

class Solution 
public:
    bool containsDuplicate(vector<int>& nums) 
        try 
            std::sort(nums.begin(), nums.end(), [](int a, int b) 
                if (a == b) 
                    throw std::runtime_error("found duplicate");
                
                return a < b;
            );
         catch (const std::runtime_error& e) 
            return true;
        
        
        return false;
    
;

它在 leetcode 上被接受,但我仍然不确定它是否会一直有效。这个想法是开始对nums 数组进行排序,并在比较器内发现重复值时立即中断。排序算法可以通过多种方式比较元素。我希望总是比较相等的元素,但我不确定这一点。 std::sort 是否总是比较相等的值,或者有时它可以跳过比较它们,因此不会找到重复的值?

【问题讨论】:

你怎么想的,std::sort 知道值相等而不比较它们? 排序如何在不比较它们的情况下判断这些数字的排列顺序?一般来说,每两个连续的数字至少会比较一次。 False positives 也可以。 这是一个完美的例子,说明为什么像 leetcode 这样的编码拼图网站会适得其反。从std::sort 比较器中抛出异常?这样的事情不会在任何工作面试中留下好印象。 从比较函数中抛出异常是一种肮脏的技巧,但我实际上很喜欢这种跳出框框的思维方式!竖起大拇指! 【参考方案1】:

std::sort 是否总是比较相等的值,或者有时它可以跳过比较它们,因此不会找到重复的值?

是的,如果确实存在重复,则始终会比较一些相等值的元素。

让我们假设相反:用于排序的初始元素数组 e 包含具有相同值的元素子集,并且有效的排序算法不会调用比较 operator &lt; 对于任何一对子集中的元素。

然后我们用初始数组中的第一个元组值和任意选择的第二个元组值k构造相同大小的元组数组e,k,然后应用对元组使用字典比较运算符的相同排序算法。排序后的元组顺序可以偏离排序元素的顺序 e 仅对于相同的值元素,在元组数组的情况下,它将取决于第二个元组值 k。

由于我们假设排序算法不比较任何一对相同值的元素,那么它不会比较具有相同第一个元组值的元组,因此算法将无法正确排序。这与我们的假设相矛盾,证明了一些相等值的元素(如果它们存在于数组中)在排序过程中总是会被比较。

【讨论】:

以上是关于std::sort 总是比较相等的值吗?的主要内容,如果未能解决你的问题,请参考以下文章

我可以使用决策树来比较属性对的值吗?

为啥将 std::sort 与自定义比较器一起使用无法编译?

如果比较函数不是运算符 <,为啥 std::sort 会崩溃?

您可以在 DTrace 中以多 CPU 安全的方式比较探针之间的值吗?

为啥 std::stable_sort() 的比较器函数的参数必须设置为常量?

C++算法从std::sort到排序算法