我有一个非重叠范围列表(数字范围,例如500-1000,1001-1200 ......等),是否有一种优雅而快速的方法只通过一个数字进行查找?我可以使用List.BinarySearch()或Array.BinarySearch()但我必须传递范围对象的类型(Array.BinarySearch(T [],T)),我可以传递一个虚拟范围对象并完成工作(只与范围开始比较)但我想知道是否可以通过传递一个整数并获取范围对象以更清洁的方式完成,有没有办法实现这一点?
三种选择:
创建一个虚拟范围并将其吸收.Urgh.
只针对这种情况手工制作二进制搜索.还不错.
在给定IRangeComparer的情况下,对任何IList和TValue进行二进制搜索.我在这里的名字"TRange"并不狂热 - 我们不一定谈论范围,而只是根据两种不同类型之间的比较来找到合适的位置.
第三种选择是这样的:
public interface IRangeComparer{ /// /// Returns 0 if value is in the specified range; /// less than 0 if value is above the range; /// greater than 0 if value is below the range. /// int Compare(TRange range, TValue value); } ////// See contract for Array.BinarySearch /// public static int BinarySearch(IList ranges, TValue value, IRangeComparer comparer) { int min = 0; int max = ranges.Count-1; while (min <= max) { int mid = (min + max) / 2; int comparison = comparer.Compare(ranges[mid], value); if (comparison == 0) { return mid; } if (comparison < 0) { min = mid+1; } else if (comparison > 0) { max = mid-1; } } return ~min; }
如果我有任何一个一个错误,请道歉.我根本没有测试它,但它至少编译:)