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

时间:2010-08-16 11:54:35

标签: c# arrays search

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

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

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

5 个答案:

答案 0 :(得分:22)

使用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];
}

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

答案 1 :(得分:5)

使用Linq:

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

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

请注意,如果Max过滤器没有元素,则对Where的调用将抛出异常,因此您可能需要检查是否有可能。

答案 2 :(得分:3)

我会选择一个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...

答案 3 :(得分:2)

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;
}

答案 4 :(得分:1)

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

public static int SearchForLimit(this IEnuemerable<int> sequence, Predicate<int> 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);