自定义类型的二进制搜索数组
本文关键字:搜索 数组 二进制 类型 自定义 | 更新日期: 2023-09-27 18:01:20
>我有一个对象的数组A,每个对象都有公共字段值(双精度(,它在0到1之间具有随机双精度。A 按此字段排序。我创建双随机 = 0.25。现在我想用 A[index] 从 A 中找到第一个对象。值>= 随机。我可以以某种方式使用 int index = Array.BinarySearch(( 来做到这一点吗?
下面是您可以使用的BinarySearch
实现。 除了通常接受的其他参数外,它还接受一个selector
,该确定应为每个项目比较的实际对象,并且对于要查找的值,它接受该类型的值,而不是数组的类型。
public static int BinarySearch<TSource, TKey>(this IList<TSource> collection
, TKey item, Func<TSource, TKey> selector, Comparer<TKey> comparer = null)
{
return BinarySearch(collection, item, selector, comparer, 0, collection.Count);
}
private static int BinarySearch<TSource, TKey>(this IList<TSource> collection
, TKey item, Func<TSource, TKey> selector, Comparer<TKey> comparer
, int startIndex, int endIndex)
{
comparer = comparer ?? Comparer<TKey>.Default;
while (true)
{
if (startIndex == endIndex)
{
return startIndex;
}
int testIndex = startIndex + ((endIndex - startIndex) / 2);
int comparision = comparer.Compare(selector(collection[testIndex]), item);
if (comparision > 0)
{
endIndex = testIndex;
}
else if (comparision == 0)
{
return testIndex;
}
else
{
startIndex = testIndex + 1;
}
}
}
使用它很简单:
public class Foo
{
public double Value { get; set; }
}
private static void Main(string[] args)
{
Foo[] array = new Foo[5];
//populate array with values
array.BinarySearch(.25, item => item.Value);
}
最好的方法是自己动手。
public static class ListExtensions
{
public static T BinarySearchFirst<T>(this IList<T> list, Func<T, int> predicate)
where T : IComparable<T>
{
int min = 0;
int max = list.Count;
while (min < max)
{
int mid = (max + min) / 2;
T midItem = list[mid];
int comp = predicate(midItem);
if (comp < 0)
{
min = mid + 1;
}
else if (comp > 0)
{
max = mid - 1;
}
else
{
return midItem;
}
}
if (min == max &&
predicate(list[min]) == 0)
{
return list[min];
}
throw new InvalidOperationException("Item not found");
}
}
用法:
var list = Enumerable.Range(1, 25).ToList();
var mid = list.Count / 2; //13
list.BinarySearchFirst(c => c >= 23 ? 0 : -1); // 23
基于 LINQ 是否可以在对集合进行排序时使用二进制搜索?