c# - 为什么我的 OrderBy 使用这个比较器永远运行?

标签 c# .net algorithm sorting

我有课,

public class NullsAreLast : IComparer<int?>
{
    public int Compare (int? x, int? y)
    {
        if(y == null)
            return -1;
        else if(x == null)
            return 1;
        else
            return (int)x - (int)y;
    }
}

它的工作原理不言自明。

每当我运行时

arr.OrderBy(i => i, new NullsAreLast())

arr 中至少有两个 null 值,它会永远运行!知道为什么吗?

最佳答案

请记住,排序算法可能会在对整个序列进行排序的过程中多次比较相同的两个值。因此,了解所有三种可能的结果非常重要:小于、大于和等于。

这(大部分)对于最后的整数比较(减法运算)没问题。使用 float 而不是整数时,会出现一些奇怪/罕见的边缘情况,调用 .CompareTo() 无论如何是首选做法,但在这种情况下减法通常就足够了。但是,这里的 null 检查是一个真正的问题。

想一想当一个列表即将完成排序时会发生什么。您有两个 null 值,它们都已排在列表的前面;该算法只需要验证它们处于正确的位置。因为 xy 都是 null,所以您的函数应该返回 0。它们是等效的(至少为此目的)。相反,代码总是返回 -1y 值将始终小于 x 值,因此算法将始终认为它仍然需要交换它们。它交换,并尝试再次做同样的事情。然后再次。然后再次。然后再次。它永远无法完成。

试试这个:

public class NullsAreLast : IComparer<int?>
{
    public int Compare (int? x, int? y)
    {
        if(!y.HasValue)
        {
            if (!x.HasValue) return 0;
            return -1;
        }
        if(!x.HasValue) return 1;
        return x.Value.CompareTo(y.Value);
    }
}

关于c# - 为什么我的 OrderBy 使用这个比较器永远运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37824091/

相关文章:

c# - 将unicode转换为正确的单词

c# - 从 SqlDataReader 检索 INSERT 语句的基础异常

c# - 从 http 服务流式传输大文件

c# - 如何解决 "Native DLL libmbusmaster.dll is missing! Please deploy the DLL file into the same directory as mbusmaster.net.dll."的问题

.net - 字典与 KeyPairValue 的使用

c - QuickSort 中的分割

algorithm - 一种计算位奇偶校验的简单/按位方式

c# - 在某处写入日志和数据的正确方法

c# - 将 xamarin 表单与 IServiceProvider 一起使用

c - 算法 - 对 "n"输入文件进行排序并生成单个输出文件的最佳方法是什么