2016-05-11 5 views
0

Хорошо, говорят, у меня есть строго типизированный SortedSet типа int. Я хочу найти наибольшее число в наборе, которое меньше x.Как эффективно искать сортировку с неравенством?

Возможно, это неправильная структура данных для этого, но мое интуитивное мышление состоит в том, что у меня есть отсортированная коллекция. Конечно, имеет смысл, что я должен выполнять этот тип поиска через платформу .NET?

ответ

2

Поскольку SortedSet не обеспечивает прямой доступ по индексу, вы должны полагаться на перечисление (линейный поиск - O (п)). Возможно, лучшим способом является использование SortedSet.GetViewBetween и Last, но это не похоже на то, что вы можете получить последний элемент без перечисления всех элементов в поле зрения.

Коллекция с прямым доступом по индексу (т.е. List) позволит вам сделать бинарный поиск с O (Lg п) производительность - так что если вам нужно искать много копирования в список мог с ToList дать лучшую производительность при использовании List.BinarySearch (которые дают вам позицию следующего элемента тому, который вы ищете).

// starting sample for BinarySearch approach 
// not handling case where item not in the list (x = 1). 
// List have to be sorted which is the case starting from sorted set: sortedSet.ToList() 
var list = new List<int>{ 1,3, 5, 7, 8,9}; 
var index = list.BinarySearch(8); 
Console.WriteLine(index < 0 ? list[~index - 1] : list[index-1]); 
+1

Стоит отметить, что список должен быть заказан перед выполнением BinarySearch - из раздела примечаний на странице msdn: «Список уже должен быть отсортирован в соответствии с реализацией сравнения, в противном случае результат будет неправильным». –

+0

@zohar OP начинается с SortedSet, поэтому ToList в такой коллекции будет производить отсортированный список. Действительно, если начать с некоторых других данных, сортировка будет первым шагом, но это будет еще хуже, чем оригинальный линейный поиск. –

+0

Я полностью согласен с вами, поэтому я поддержал ваш ответ, но это то, что я думаю, стоит упомянуть - ваш пример не использовал '.ToList()' на упорядоченном наборе ... –

2

Если я что-то отсутствует, используйте метод LastOrDefault расширения Linq в:

var lastBefore = set.LastOrDefault(num => num < x); // x is your search number 
if (lastBefore < set.ElementAt(0)) 
{ 
    // Nothing in the set is smaller 
} 
else 
{ 
    // lastBefore is the last number smaller then search number 
} 
+0

Обратите внимание, что это O (n), даже если коллекция сортируется, и обычно можно ожидать производительность O (lg n), но это лучший результат с 'SortedSet', насколько мне известно. –

Смежные вопросы