代码之家  ›  专栏  ›  技术社区  ›  mustafabar

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

  •  10
  • mustafabar  · 技术社区  · 16 年前

    int[] ,我要搜索最接近某个输入数字的较小值。

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

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

    5 回复  |  直到 16 年前
        1
  •  22
  •   Quartermeister    16 年前

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

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

        2
  •  5
  •   fearofawhackplanet    16 年前

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

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

    请注意,调用 Max 如果 Where 过滤器不会产生任何元素,所以如果可能的话,您可能需要检查它。

        3
  •  3
  •   Tim Cooper    15 年前

    更新 :要添加更多代码以避免与fear的类似解决方案相似,请执行以下操作:

    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...
    
        4
  •  2
  •   user3483642    12 年前
    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;
    }
    
        5
  •  1
  •   Rune FS    16 年前

    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);
    
    推荐文章