Использование Array.BinarySearch () для возврата первого значения <= значение поиска? - PullRequest
1 голос
/ 10 августа 2010

Я пытаюсь создать столбец «поиска», который бы возвращал индекс значения массива, равного или меньшего, чем искомого значения. Так что это моя попытка, которая, кажется, работает нормально, но мне было интересно, есть ли более чистый способ сделать это?

// Sorted
float[] ranges = new float[]
  {
     0.8f,
     1.1f,
     2.7f,
     3.9f,
     4.5f,
     5.1f,
  };


private int GetIndex(float lookupValue)
{
    int position = Array.BinarySearch(ranges, lookupValue);
    if (position < 0)
    {
        // Find the highest available value that does not
        // exceed the value being looked up.
        position = ~position - 1;
    }

    // If position is still negative => all values in array 
    // are greater than lookupValue, return 0
    return position < 0 ? 0 : position;
}

Спасибо.

Ответы [ 2 ]

3 голосов
/ 11 августа 2010

Нет, я думаю, что это довольно хороший подход.

Единственное, что я могу изменить, это сделать его методом расширения для массивов, а не частной функцией, ссылающейся на переменную класса.Затем он становится общим / не привязанным к одному классу, и синтаксис тоже чище: ranges.GetIndex(...)

Примерно так:

public static class Extensions
{
    public static int GetIndex<T>(this T[] ranges, T lookupValue)
    {
        // your code here
    }
}

Конечно, вам придется запомнитьработает только на отсортированных массивах ...

1 голос
/ 11 августа 2010

Вы можете использовать обычный цикл for (при условии, что ваши данные упорядочены). Не уверен, что это чище, но, конечно, не так эффективно для большого количества данных. Лично я бы пошел на бинарный поиск, который у вас есть.

int GetIndex(IList<float> ranges, float target)
{
    for (int i = 0; i < ranges.Count; i++)
    {
        if(ranges[i] < target) continue;
        if (ranges[i] >= target) return i;
    }
    return 0;
}
...