在排序数组中找到小于x的最大值

假设我有一个整数的整数int[] ,我想搜索最接近的较小值到某个输入数。

例如,如果数组包含(1),(23),(57),(59),(120)并且输入为109,则输出应为59。

我只是想看看建议,并与我已有的方法进行比较。

使用Array.BinarySearch 。 如果输入在列表中,它将返回索引,如果不是,则它将返回第一个较大值的索引的补码。 您只需反转结果并减去一个以获得最接近的较小值的索引。

 int[] arr = { 1, 23, 57, 59, 120 }; int index = Array.BinarySearch(arr, 109); if (index < 0) { index = ~index - 1; } if (index >= 0) { var result = arr[index]; } 

请注意,如果输入小于最小元素,则没有明确定义的答案。

使用Linq:

 int[] arr = new[] { 1, 23, 57, 59, 120 }; int target = 109; int max = arr.Where(n => n < target).Max(); 

也许不是最快但可能最容易实现的。 也不依赖于正在排序的数组,就像二进制搜索一样。

请注意,如果Wherefilter没有元素,则对Max的调用将抛出exception,因此您可能希望检查是否可能。

我会选择一个linq解决方案( 更新 :添加一些代码来阻止类似于恐惧的类似解决方案):

 int[] arr1 = { 1, 23, 57, 59, 120 }; int maxResult; string errorMsg; try { maxResult = arr1.Where(x => x <= 109).Max(); } catch(Exception e) { errorMsg = e.Message; // do some error stuff here :) return null; } // party on your maxResult... 
 int getIndex( long[] list, long value ) { int top = 0; int bot = list.length-1; int mid=0; while ( top <= bot ) { mid = (top+bot)/2; // NB integer arithmetic if ( value < list[mid] ) { if ( mid == 0 ) // value < than first item return -1; else bot = mid-1; } else // value >= list[mid] { if ( mid == list.length-1 ) // value is >= last item break; else if ( value >= list[mid+1] ) top = mid+1; else // list[mid] must be biggest <= value break; } } return mid; } 

只是为了推断其他LINQ解决方案,如果没有对象适合filter并且期望​​列表都是正整数,则此扩展方法将返回-1

 public static int SearchForLimit(this IEnuemerable sequence, Predicate filter) { return (from i in sequence let n = filter(i) ? i : -1 select n).Max() } 

用法看起来像这样:

 int[] arr1 = { 1, 23, 57, 59, 120 }; int limitedBy109 = arr1.SearchForLimit(i => i < 109);