[英]How to use BinarySearch for List<T>
讓我們從List BinarySearch的重載開始:
public int BinarySearch(T item, IComparer<T> comparer);
眾所周知,在使用BinarySearch之前,應該使用適當的IComparer對列表進行排序。 但是:要搜索列表,您必須提供T項。 當使用一個基於這些項的屬性(即使用Linq或delegates /謂詞)來搜索列表中的項時,這是相當意外的。 因為當我已經擁有我的T項時,我不必搜索它!
現在我在C#中實現C ++代碼,看到C ++程序員在他的代碼中到處使用C ++樣式二進制搜索,如下所示。 首先,他制作了一個新的T項目並給了這個T項目他正在尋找的屬性。 然后他用它搜索列表,找到具有相同屬性的列表中項目的索引 。 當然,C ++比較器適用於這些屬性。
所以這是在List中查找項目的一種完全不同的方式。 BinarySearch創建一個虛擬 T項並搜索一個索引,用它可以檢索列表中的實際 T項。 從Linq的角度來看,這感覺不自然。
我的問題是:
我是否正確描述了BinarySearch背后的想法?
您是否認為可以使用Linq樣式搜索BinarySearch而不首先制作虛擬T項目?
Did I give a correct description of the idea behind BinarySearch?
是。
Do you think it is possible to use a Linq style search with BinarySearch without making a dummy T item first?
不是它的當前形式。 你可以使用一個為你創建虛擬T的包裝器,它只適用於特定的Ts,但是(使用無參數構造函數等)。
實際上,LINQ中沒有類似內容,但您可以構建自己的擴展。 此示例允許您不傳遞虛擬項,但僅作為原始比較器中使用的屬性:
public static int FindFirstIndexGreaterThanOrEqualTo<TElement, TKey>(
this IList<TElement> keySortedCollection,
TKey key,
Func<TElement, TKey> keySelector,
IComparer<TKey> keyComparer)
{
int begin = 0;
int end = keySortedCollection.Count;
while (end > begin)
{
int index = (begin + end) / 2;
TElement el = keySortedCollection[index];
TKey currElKey = keySelector(el);
if (keyComparer.Compare(currElKey, key) >= 0)
end = index;
else
begin = index + 1;
}
return end;
}
public static int FindFirstIndexGreaterThanOrEqualTo<TElement, TKey>(
this IList<TElement> keySortedCollection,
TKey key,
Func<TElement, TKey> keySelector)
{
return FindFirstIndexGreaterThanOrEqualTo(keySortedCollection,
key,
keySelector,
Comparer<TKey>.Default);
}
使用這些方法,您可以進行比較,該比較是您最初用於對集合進行排序的一個子集。
顯然,當您使用原始比較器的子集時,您無法確定找到單個索引。 因此,這些方法返回較低的二進制搜索范圍。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.