Получить значение по умолчанию для целых типов - PullRequest
0 голосов
/ 05 сентября 2018

Алгоритм из Leetcode Discussion использует двоичное дерево поиска для хранения диапазона значений из входного массива, чтобы проверить, содержит ли этот массив значения, отличающиеся не более чем на t, и их индексы не более чем на k друг от друга.

JAVA :

public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
    if (nums == null || nums.length == 0 || k <= 0) {
        return false;
    }

    final TreeSet<Integer> values = new TreeSet<>();
    for (int ind = 0; ind < nums.length; ind++) {

        final Integer floor = values.floor(nums[ind] + t);
        final Integer ceil = values.ceiling(nums[ind] - t);

        if ((floor != null && floor >= nums[ind])
                || (ceil != null && ceil <= nums[ind])) {
            return true;
        }

        values.add(nums[ind]);
        if (ind >= k) {
            values.remove(nums[ind - k]);
        }
    }
    return false;
}

Я изо всех сил пытаюсь заставить это работать в C #. Этот код не работает, пока методы LastOrDefault и FirstOrDefault возвращают 0 по умолчанию. Как обойти, чтобы получить null по умолчанию?

C #

public bool ContainsNearbyAlmostDuplicate(int[] nums, int k, int t)
{
    if (nums == null || nums.Length < 2 || k < 1) return false;

    SortedSet<long> set = new SortedSet<long>();

    for (int i = 0; i < nums.Length; i++)
    {
        long l = (long)nums[i];

        long floor = set.LastOrDefault(n => n <= l);
        long ceil = set.FirstOrDefault(n => n >= l);

        if ((l - floor <= t) || (ceil - l <= t))
            return true;

        set.Add(l);
        if (i >= k) set.Remove((long)nums[i - k]);
    }
    return false;
}

Ответы [ 6 ]

0 голосов
/ 05 сентября 2018

Если вы хотите объявить значения int, long ... как NULL, вам нужно объявить так:

int? empId;
if(empId is null)
{
    // do this
}
else
{
    //do this
}

Точно так же вы должны использовать:

SortedSet<long?> sortedSet = new SortedSet<long?>();
0 голосов
/ 05 сентября 2018

Вы можете преобразовать int / long в обнуляемый тип (?), Как заявили другие пользователи, и затем использовать DefaultIfEmpty для создания коллекции по умолчанию, содержащей ноль, если коллекция оказывается пустой.

SortedSet<long?> set = new SortedSet<long?>();

long? floor = set.Where(n => n <= l).DefaultIfEmpty().LastOrDefault();
long? ceil = set.Where(n => n >= l).DefaultIfEmpty().FirstOrDefault();
0 голосов
/ 05 сентября 2018

Другие ответы технически правильны (используйте типы nullable на вашем наборе)

SortedSet<long?> set = new SortedSet<long?>();

Однако, чтобы получить нулевое значение от FirstOrDefault / LastOrDefault, вам нужно передать int?[] nums в ваш метод, потому что вы заполняете свой набор путем приведения

long l = (long)nums[i];

, который не получит нулевое значение из массива int даже при приведении к значению nullable long?.

Другими словами - для работы с нулевыми значениями вашему методу требуется получить массив с нулевым значением.

И если вы никогда не будете работать с пустыми значениями в предоставленном массиве, почему бы просто не выполнить итерацию с i = 1?

0 голосов
/ 05 сентября 2018

Если вы хотите получить значения типа int / long / ..., включая NULL, вам необходимо указать Nullable Types

А в вашем исходном коде будет:

 SortedSet<long?> set = new SortedSet<long?>();
0 голосов
/ 05 сентября 2018

Один из способов - объявить ваш сет с длинными значениями

var set = new SortedSet<long?>();

Или вы можете просто не использовать FirstOrDefault и сделать что-то вроде:

var greaterOrEqualToOne = set.Where(n => n >= 1);

long? ceil = greaterOrEqualToOne.Any() ? greaterOrEqualToOne.First() : null;

Еще один способ, сначала приведите их к long?:

long? ceil = set.Select(n => (long?)n).FirstOrDefault(n => n >= 1);
0 голосов
/ 05 сентября 2018

Используйте значение Nullable long, чтобы получить значение NULL в LastOrDefault

SortedSet<long?> set = new SortedSet<long?>();
...