簡體   English   中英

如何使用BinarySearch for List <T>

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM