Algorithm 修改二进制搜索以查找下一个比键大的项

Algorithm 修改二进制搜索以查找下一个比键大的项,algorithm,binary-search,Algorithm,Binary Search,我想修改著名的算法,以返回下一个较大项的索引,而不是正在搜索的键 因此,我们有4个案例: 键小于所有项,返回0 键大于所有项,返回items.length 该键位于索引x处,返回x+1 找不到键,请返回下一个较大键的索引 e、 g: 搜索0返回0 搜索11或12返回6 搜索5或6返回3 while (low <= high) { mid = (low + high) / 2; if (data[mid] < val) low = mid + 1;

我想修改著名的算法,以返回下一个较大项的索引,而不是正在搜索的键

因此,我们有4个案例:

  • 键小于所有项,返回0
  • 键大于所有项,返回items.length
  • 该键位于索引x处,返回x+1
  • 找不到键,请返回下一个较大键的索引
  • e、 g:

    • 搜索0返回0
    • 搜索11或12返回6
    • 搜索5或6返回3

      while (low <= high) {
          mid = (low + high) / 2;
          if (data[mid] < val)
              low = mid + 1;
          else if (data[mid] > val)
              high = mid - 1;
          else {
              break;
          }
      }
      
      while(低值)
      高=中-1;
      否则{
      打破
      }
      }
      
    目前通过检查低值和高值使其工作。 是否有任何有趣的代码可以这样做

    编辑

    以下是我如何让它工作的:

        if (low <= high)
            found = (low + high) / 2 + 1;
        else if (low >= data.length)
            found = data.length ;
        else if (high < 0)
            found = -1;
        else
            found = low;
    
    if(低=数据长度)
    found=data.length;
    否则如果(高<0)
    发现=-1;
    其他的
    发现=低;
    
    我在寻找一种更优雅的方式

    编辑二

    如果没有重复的代码,则此代码有效。 要处理重复的情况,我们需要修改第一个if条件:

    if (low <= high)
        found = (low + high) / 2 + 1;
    

    if(low这是您想要的。它返回下一个较大的元素

    public int binarySearch(int[] arr, int key) {
        int lo = 0;
        int hi = arr.length - 1;int mid = 0;
        while (lo <= hi) {
            mid = (lo + hi) / 2;
            if      (key < arr[mid]) hi = mid - 1;
            else if (key > arr[mid]) lo = mid + 1;
            else return mid;
        }
        return -Math.min(lo, hi)-2;
    }
    
    
    public int myBinarySearch(int[] arr, int key){
         int x = binarySearch(arr, key);
         if(x >= arr.length-1 || -x > arr.length){
             //whatever you want to return
             return Integer.MAX_VALUE;
         }
         else if(x >= 0)
              return arr[x+1] ;
         else
              return arr[-x-1];
    }
    public static void main(String args[]) {
        Triall tr = new Triall();
        int arr[] = { 1, 3, 5, 7, 9, 11 }; 
        for( int i = 0; i < 13; i++ ) { 
            int n = tr.myBinarySearch( arr,i ); 
            System.out.println(i + " " + n ); 
        }
    }
    
    public int-binarySearch(int[]arr,int-key){
    int-lo=0;
    int hi=arr.length-1;int mid=0;
    而(lo arr[mid])lo=mid+1;
    否则返回中间;
    }
    return-Math.min(lo,hi)-2;
    }
    公共int-myBinarySearch(int[]arr,int-key){
    int x=二进制搜索(arr,key);
    如果(x>=arr.length-1 | |-x>arr.length){
    //无论你想要什么回报
    返回Integer.MAX_值;
    }
    如果(x>=0),则为else
    返回arr[x+1];
    其他的
    返回arr[-x-1];
    }
    公共静态void main(字符串参数[]){
    Triall tr=新的Triall();
    int arr[]={1,3,5,7,9,11};
    对于(int i=0;i<13;i++){
    int n=tr.myBinarySearch(arr,i);
    系统输出打印项次(i+“”+n);
    }
    }
    
    以下是一些满足OP搜索要求的C代码:

    • 值<第一项:返回0
    • 值包含在数组中:找到返回索引+1
    • 值不在数组中,但
    • 值>=最后一项:返回数组大小
    它还演示了4种不同类型的二进制搜索:

    • 标准二进制搜索
    • Lessthan相等二进制搜索
    • lessthan等于或最后一个二进制搜索
    • 下一个最大的二进制搜索
    (假设
    数据中没有重复项

    #包括
    int二进制搜索(int键,int数据[],常量int len)
    {
    int低=0;
    int高=len-1;
    而(高>=低)
    {
    int mid=低+((高-低)/2);
    /**/如果(数据[中间]<键)低=中间+1;
    否则,如果(数据[mid]>键)高=中-1;
    否则返回中间;
    }
    return-1;//找不到键
    }
    int-LessThanEqualBinSearch(int-key,int-data[],const-int-len)
    {
    int min=0;
    int max=len-1;
    //var max=data.length-1;//Javascript,Java转换
    而(最小键)max=mid-1;
    else/*数据[mid]=键)*/返回mid;
    }
    如果(最大值<0)
    返回0;//键<数据[0]
    其他的
    如果(最小值>最小值(len-1))
    返回-1;//key>=数据[len-1]//找不到key
    其他的
    返回(最小值<最大值)
    ? 闵
    :最大值+1;
    }
    int-lessthanequallastbinsearch(int-key,int-data[],const-int-len)
    {
    int min=0;
    int max=len-1;
    //var max=data.length-1;//Javascript,Java转换
    而(最小键)max=mid-1;
    else/*数据[mid]=键)*/返回mid;
    }
    如果(最大值<0)
    返回0;//键<数据[0]
    其他的
    如果(最小值>最小值(len-1))
    返回len-1;//键>=数据[len-1]
    其他的
    返回(最小值<最大值)
    ? 闵
    :最大值+1;
    }
    int-NextLargestBinSearch(int-key,int-data[],const-int-len)
    {
    int低=0;
    int高=len-1;
    而(低调)高=中-1;
    否则返回mid+1;
    }
    如果(高<0)
    返回0;//键<数据[0]
    其他的
    如果(低>(len-1))
    返回len;//键>=数据[len-1]
    其他的
    返回(低<高)
    ? 低+1
    :高+1;
    }
    int main()
    {
    int项[]={1,3,5,7,9,11};
    int LENGTH=sizeof(items)/sizeof(items[0]);
    对于(int i=-1;i<14;++i)
    printf(“[%2d]:===%2d”
    
  • 列表项
  • 下面是一个代码:

    • 如果元素存在,则返回要搜索的元素的索引
    • 如果数组中不存在搜索的元素,则返回下一个较大元素的索引
    • 如果搜索大于数组最大元素的元素,则返回-1
    公共静态int-ceilSearch(int-arr[],int-low,int-high,int-x){
    int mid;
    如果(x arr[高])
    返回-1;
    中=(低+高)/2;/*低+(高-低)/2*/
    如果(arr[mid]==x)
    中途返回;
    否则如果(arr[mid]
    您正在实现的算法。“搜索4或5返回3”错误!搜索4应返回2,搜索5应返回3。@ElKamina更正了搜索5或6返回3!实际上我想实现我的二进制搜索版本,而不是使用集合。binarySearch()@smttsp仅当数组中没有重复项时,此方法才有效。如果有三个相同的项,并且二进制搜索返回其中的第一个或第二个项,则您的方法将不会返回下一个较大的项。在二进制搜索后,您必须向上扫描数组以查找不同的值。我发现这不起作用。在至少可以帮你找到一些东西:)这段代码仍然很糟糕:int-arr[]={1,3
    public int binarySearch(int[] arr, int key) {
        int lo = 0;
        int hi = arr.length - 1;int mid = 0;
        while (lo <= hi) {
            mid = (lo + hi) / 2;
            if      (key < arr[mid]) hi = mid - 1;
            else if (key > arr[mid]) lo = mid + 1;
            else return mid;
        }
        return -Math.min(lo, hi)-2;
    }
    
    
    public int myBinarySearch(int[] arr, int key){
         int x = binarySearch(arr, key);
         if(x >= arr.length-1 || -x > arr.length){
             //whatever you want to return
             return Integer.MAX_VALUE;
         }
         else if(x >= 0)
              return arr[x+1] ;
         else
              return arr[-x-1];
    }
    public static void main(String args[]) {
        Triall tr = new Triall();
        int arr[] = { 1, 3, 5, 7, 9, 11 }; 
        for( int i = 0; i < 13; i++ ) { 
            int n = tr.myBinarySearch( arr,i ); 
            System.out.println(i + " " + n ); 
        }
    }
    
    #include <stdio.h>
    
    int BinarySearch( int key, int data[], const int len )
    {
        int low  = 0;
        int high = len-1;
    
        while( high >= low )
        {
            int mid = low + ((high - low) / 2);
    
            /**/ if (data[mid] < key) low  = mid + 1;
            else if (data[mid] > key) high = mid - 1;
            else return                      mid    ;
        }
        return -1; // KEY_NOT_FOUND
    }
    
    int LessThanEqualBinSearch( int key, int data[], const int len )
    {
        int min = 0;
        int max = len-1;
        // var max = data.length - 1; // Javascript, Java conversion
    
        while( min <= max)
        {
            int mid = min + ((max - min) / 2);
    
            /**/ if (data[mid] < key)  min  = mid + 1;
            else if (data[mid] > key)  max  = mid - 1;
            else   /*data[mid] = key)*/return mid    ;
        }
    
        if( max < 0 )
            return 0;  // key < data[0]
        else
        if( min > (len-1))
            return -1; // key >= data[len-1] // KEY_NOT_FOUND
        else
            return (min < max)
                ? min  
                : max + 1;
    }
    
    int LessThanEqualOrLastBinSearch( int key, int data[], const int len )
    {
        int min = 0;
        int max = len-1;
        // var max = data.length - 1; // Javascript, Java conversion
    
        while( min <= max)
        {
            int mid = min + ((max - min) / 2);
    
            /**/ if (data[mid] < key)  min  = mid + 1;
            else if (data[mid] > key)  max  = mid - 1;
            else   /*data[mid] = key)*/return mid    ;
        }
    
        if( max < 0 )
            return 0;     // key < data[0]
        else
        if( min > (len-1))
            return len-1; // key >= data[len-1]
        else
            return (min < max)
                ? min  
                : max + 1;
    }
    
    int NextLargestBinSearch( int key, int data[], const int len )
    {
        int low  = 0;
        int high = len-1;
    
        while( low <= high)
        {
            // To convert to Javascript:
            // var mid = low + ((high - low) / 2) | 0;
            int mid = low + ((high - low) / 2);
    
            /**/ if (data[mid] < key) low  = mid + 1;
            else if (data[mid] > key) high = mid - 1;
            else return                      mid + 1;
        }
    
        if( high < 0 )
            return 0;   // key < data[0]
        else
        if( low > (len-1))
            return len; // key >= data[len-1]
        else
            return (low < high)
                ? low  + 1
                : high + 1;
    }
    
    int main()
    {
        int items[] = { 1, 3, 5, 7, 9, 11 };
        int LENGTH  = sizeof(items) / sizeof(items[0]);
    
        for( int i = -1; i < 14; ++i )
            printf( "[%2d]: == %2d   <= %2d   <| %d   > %d\n", i
            , BinarySearch                ( i, items, LENGTH )
            , LessThanEqualBinSearch      ( i, items, LENGTH )
            , LessThanEqualOrLastBinSearch( i, items, LENGTH )
            , NextLargestBinSearch        ( i, items, LENGTH )
        );   
    
        return 0;
    }
    
    [-1]: == -1   <=  0   <| 0   > 0
    [ 0]: == -1   <=  0   <| 0   > 0
    [ 1]: ==  0   <=  0   <| 0   > 1
    [ 2]: == -1   <=  1   <| 1   > 1
    [ 3]: ==  1   <=  1   <| 1   > 2
    [ 4]: == -1   <=  2   <| 2   > 2
    [ 5]: ==  2   <=  2   <| 2   > 3
    [ 6]: == -1   <=  3   <| 3   > 3
    [ 7]: ==  3   <=  3   <| 3   > 4
    [ 8]: == -1   <=  4   <| 4   > 4
    [ 9]: ==  4   <=  4   <| 4   > 5
    [10]: == -1   <=  5   <| 5   > 5
    [11]: ==  5   <=  5   <| 5   > 6
    [12]: == -1   <= -1   <| 5   > 6
    [13]: == -1   <= -1   <| 5   > 6
    
          public static int ceilSearch(int arr[], int low, int high, int x) {
        int mid;
        if (x <= arr[low])
          return low;
        if (x > arr[high])
          return -1;
    
        mid = (low + high) / 2; /* low + (high - low)/2 */
    
        if (arr[mid] == x)
          return mid;
    
        else if (arr[mid] < x) {
          if (mid + 1 <= high && x <= arr[mid + 1])
            return mid + 1;
          else
            return ceilSearch(arr, mid + 1, high, x);
        } else {
          if (mid - 1 >= low && x > arr[mid - 1])
            return mid;
          else
            return ceilSearch(arr, low, mid - 1, x);
        }
      }