【发布时间】:2016-03-28 00:47:35
【问题描述】:
我的书C# 3.0 Cookbook by O'Reilly 有以下让我感到困惑的例子。 (下面是准确的转录。)
// 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))
sn-p。根据the documentation on the BinarySearch 方法,left 是元素的索引。那么条件如何
left < 0 && myList[left-1].Equals(searchValue)
在while 循环中有意义吗?由于短路,如果left < 0 则评估右侧myList[left-1].Equals(searchValue) 但myList[left-1] 正在访问负索引!对吧?
我确实阅读了有关如果找不到元素在 BinarySearch 中会发生什么的部分
一个负数,它是索引的按位补码 下一个大于 item 的元素,或者,如果没有更大的元素 元素,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;
}
【问题讨论】:
-
请注意,该方法的最坏情况复杂度可能是 O(n)。当列表的所有元素都相同时就会如此。
-
在 2010 年 12 月 1 日有一个 errata item 报告了此问题,但 O'Reilly 并未正式确认。
标签: c# algorithm binary-search-tree