Найдите разницу с ближайшим большим числом и ближайшим меньшим числом в списке - PullRequest
0 голосов
/ 01 февраля 2019

У меня есть список целых чисел, и я хочу найти разницу с ближайшим меньшим числом и разницу с ближайшим более высоким числом из заданного 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) * /

Ответы [ 4 ]

0 голосов
/ 01 февраля 2019

В основном ответ Кирилла, но чище:

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;
    }
}
0 голосов
/ 01 февраля 2019

Хотя это можно сделать в 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}");
0 голосов
/ 01 февраля 2019

Вы можете сделать следующее.

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;

Выход closestLower: 1 closestHigher: 3

0 голосов
/ 01 февраля 2019

Это, вероятно, полуэффективный способ сделать это (в зависимости от данных он может быть более эффективным без сортировки):

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)));

Выходы:

Closest low: 4, Closest high: 8, Distance low: 1, Distance high: 3

Попробуйте онлайн

Обратите внимание, что предполагается, что по крайней мере на 1 число меньше, а на 1 больше.Если это не так, closestLowerNumber или closestHigherNumber останется 0 и даст странные результаты.Поэтому, вероятно, разумно вместо этого использовать nullable int, чтобы вы могли проверить, установлено ли оно (int? closestLowerNumber) с помощью closestLowerNumber.HasValue.

...