C# 查找列表中最接近的较高数字和最接近的较低数字之间的差异

C# 查找列表中最接近的较高数字和最接近的较低数字之间的差异,c#,list,numbers,difference,closest,C#,List,Numbers,Difference,Closest,我有一个int的列表,我想从给定的referenceNumber中找出最接近的较低数字的差值和最接近的较高数字的差值。 在这种情况下,如果referenceNumber是5。它如何输出closestLowerNumber=1和closestHigherNumber=3 List<int> Test = new List<int>() {2, 1, 4, 8 }; int referenceNumber = 5; int closestLo

我有一个int的列表,我想从给定的referenceNumber中找出最接近的较低数字的差值和最接近的较高数字的差值。 在这种情况下,如果referenceNumber是5。它如何输出closestLowerNumber=1和closestHigherNumber=3

List<int> Test = new List<int>() {2, 1, 4, 8 };

        int referenceNumber = 5;
        int closestLowerNumber;
        int closestHigherNumber;
/*closestLowerNumber是最接近的较低数字1的差值
closestHigherNumber是最接近的较高数字3的差值*/

这可能是一种半有效的方法,取决于数据,无需排序可能更有效:

var test = new List<int>() { 2, 1, 4, 8 };
int referenceNumber = 5;
int closestLowerNumber = 0;
int closestHigherNumber = 0;

foreach (var val in test.OrderBy(v => v))
{
    if (val < referenceNumber)
    {
        closestLowerNumber = val;
    }
    else if (val > referenceNumber)
    {
        closestHigherNumber = val;
        break;
    }
}

Console.WriteLine(string.Format("Closest low: {0}, Closest high: {1}, Distance low: {2}, Distance high: {3}", closestLowerNumber, closestHigherNumber, (referenceNumber - closestLowerNumber), (closestHigherNumber - referenceNumber)));

请注意,这假设至少有一个较小的数字和一个较大的数字。如果不是这种情况,closestLowerNumber或closestHigherNumber将保持0并给出奇怪的结果。因此,使用可为null的int可能是明智的,这样您就可以检查它是否被设置为int?使用closestLowerNumber.HasValue关闭stLowerNumber。

虽然这可以在LINQ中完成,但它并不是解决此任务的最有效方法。我会这样说:

int referenceNumber = 5;
int? closestLowerNumber = null;
int? closestHigherNumber = null;

foreach (var i in Test)
{
    if (i < referenceNumber)
    {
        if (!closestLowerNumber.HasValue || closestLowerNumber < i)
        {
            closestLowerNumber = i;
        }
    }
    else if (i > referenceNumber)
    {
        if (!closestHigherNumber.HasValue || closestHigherNumber > i)
        {
            closestHigherNumber = i;
        }
    }
}

Console.WriteLine(
    $"{referenceNumber}:{referenceNumber - closestLowerNumber}:{closestHigherNumber - referenceNumber}");

您可以执行以下操作

var closestLower = Test.Where(x=>x<referenceNum).Min(x=>referenceNum-x);
var closestHigher = Test.Where(x=>x>referenceNum).Min(x=>x-referenceNum);
另一种选择

var closestLower = referenceNum - Test.Where(x=>x<referenceNum).Max();
var closestHigher = Test.Where(x=>x>referenceNum).Min() - referenceNum;
输出 近距离:1
最接近的更高:3

基本上是基里尔的答案,但更干净:

var Test = new List<int>() { 2, 1, 4, 8 };
var reference = 5;

var closestLower = int.MinValue;
var closestHigher = int.MaxValue;

foreach (var value in Test) {
    switch (value.CompareTo(reference)) {
        case -1: // value < reference
            closestLower = Math.Max(closestLower, value);
            break;
        case 0: // value == reference
            break;
        case 1: // value > reference
            closestHigher = Math.Min(closestHigher, value);
            break;
    }
}

closestLowerNumber和closestLowerNumber的定义是什么closestHigherNumber@John看起来它应该返回数字和它的最近邻的差值的绝对值。abs8-5=3,abs4-5=1。@John为什么投反对票?我想将差异返回到列表中的数字,而不是列表中的数字,首先它应该找到最接近的较低数字和最接近的较高数字。我不知道为什么你决定责怪某个约翰投了否决票,因为除了让员工有权获得投票信息之外,没有人可以。。。相反,你们可能会想一想,为什么“向下投票”按钮上的工具提示会说这个问题并没有显示任何研究成果……非常感谢!。知道如何在不排序的情况下解决它吗?@Roblogic Kirill的方法:不需要最小值和最大值的计算,因为你已经过滤了小于和大于的值。只需找到较小集合的绝对最大值和较大集合的绝对最小值=@沉浸式是的,但那不会给我足够的距离,对吧?OP想要的是参考数和max/min之间的距离,而不是确切的数字。Test.Wherex=>xyes也可以有。这也将减少每个元素的计算。但也必须稍微更改min/max调用。也将使用该选项更新答案。
var Test = new List<int>() { 2, 1, 4, 8 };
var reference = 5;

var closestLower = int.MinValue;
var closestHigher = int.MaxValue;

foreach (var value in Test) {
    switch (value.CompareTo(reference)) {
        case -1: // value < reference
            closestLower = Math.Max(closestLower, value);
            break;
        case 0: // value == reference
            break;
        case 1: // value > reference
            closestHigher = Math.Min(closestHigher, value);
            break;
    }
}