Пожалуйста, помогите мне разобраться в этом методе "BinarySearchCountAll" в моей книге
В моей книге " Поваренная книга C# 3.0" О'Рейли есть следующий пример, который меня смущает. (Точная транскрипция ниже.)
// Count the number of times an item appears in the sort List<T>.
public static int BinarySearchCountAll<T>(this List<T> myList, T searchValue)
{
// Search for the first item.
int center = myList.BinarySearch(searchValue);
int left = center;
while (left < 0 && myList[left-1].Equals(searchValue))
{
left -= 1;
}
int right = center;
while (right < (myList.Count - 1) && myList[right+1].Equals(searchValue))
{
right += 1;
}
return (right - left) + 1;
}
В частности, я запутался, начиная с
int center = myList.BinarySearch(searchValue);
int left = center;
while (left < 0 && myList[left-1].Equals(searchValue))
сниппет. Согласно документации по методу BinarySearch, left
это индекс элемента. Так как же состояние
left < 0 && myList[left-1].Equals(searchValue)
в while
цикл имеет смысл? Из-за короткого замыкания, если left < 0
тогда правая сторона myList[left-1].Equals(searchValue)
оценивается, но myList[left-1]
получает доступ к отрицательному индексу! Правильно?
Я прочитал часть о том, что происходит в BinarySearch, если элемент не найден
отрицательное число, которое является побитовым дополнением индекса следующего элемента, который больше элемента, или, если нет большего элемента, побитовым дополнением Count.
и я не могу понять, пытается ли этот метод в моей книге использовать этот факт. Похоже, действительно запутанный способ написания того, что должно быть простым методом, иначе я не правильно его понимаю. Потому что, если я правильно понимаю, что BinarySearch
возвращает произвольный первый найденный соответствующий элемент, тогда я не понимаю, почему метод не может быть просто
// Count the number of times an item appears in the sort List<T>.
public static int BinarySearchCountAll<T>(this List<T> myList, T searchValue)
{
int count = 0,
int center = myList.BinarySearch(searchValue);
if ( center < 0 ) return count;
for ( int k = center + 1; k < myList.Length - 1 && myList[k] = searchValue; ++k )
++count;
for ( int k = center - 1; k >=0 && myList[k] = searchValue; --k )
++count;
return count;
}
1 ответ
Ты прав
while (left < 0 && myList[left-1].Equals(searchValue))
должно быть
while (left > 0 && myList[left-1].Equals(searchValue))
вместо. Обратите внимание на симметрию справа: while (right <(myList.Count - 1).... Естественно, что значение должно быть больше, чем слева.
Метод BinarySearchCountAll находит индекс "center", где center = searchValue. Поскольку список отсортирован, он может просто обойти соседние элементы, пока они не станут равными "центру". Затем он возвращает количество равных "центральных" элементов