二进制搜索以获取第一个整数的位置> =搜索的整数

Posted

技术标签:

【中文标题】二进制搜索以获取第一个整数的位置> =搜索的整数【英文标题】:Binary Search to get position of first integer >= searched integer 【发布时间】:2014-01-14 13:13:42 【问题描述】:

在排序数组中,我需要找到第一个整数的位置 >= 给定整数(如果数组中不存在这样的整数,则应返回-1)。以下对二分查找的修改是否正确解决了问题?我已经使用了很多测试用例来验证功能,但仍然想确认。

n = 没有。数组中的元素数

ele= 要搜索的整数

int binarySearch(int a[],int n,int ele)

  int lower=0;
  int upper=n-1;

  int mid;
  int pos=-1;
  while(lower<=upper)
  
    mid=(lower+upper)/2;
    if (a[mid]==ele)
    
        while(mid>=0 && a[mid]==ele)
            mid--;
        return mid+1;
    
    else if(a[mid]<ele)
        lower=mid+1;
    else
    
        pos=mid;
        upper=mid-1;
    
  
  return pos;

【问题讨论】:

mid=(lower+upper)/2; -- 这是broken。 即它可能会导致整数溢出。试试mid=lower+(upper - lower)/2; 为了记录,C 有一个现成的函数,叫做bsearch,它实现了二分查找。 第二个(嵌套的)while 似乎是改进的目标。理想情况下,单个 while() 应该是可能的。我认为您的代码在其他方面是正确的。当我对此进行编码时,它导致我在一个 while 循环中出现了一些问题。 【参考方案1】:

你写的不是二分查找;在最坏的情况下,它是线性搜索。 (考虑当数组包含所有相同元素时会发生什么。

信不信由你,只要编程正确,正常的二分搜索将完全满足您的需求(找到大于或等于目标的最小整数)。

我们可以借助一些不变量对其进行编程。

0 &lt;= lo &lt;= hi &lt;= n a[0..lo) &lt; x a[hi..n) &gt;= x

其中x是目标元素,a[0..lo) &lt;= x表示[0..lo)的半开区间内的所有元素都小于x

lohi 是下限和上限,首先,它们将是 0n,这使得不变量中的两个范围最初都是空的。

所以现在算法:

int 
binarySearch(int a[], int n, int x)

    int lo = 0, hi = n;

    while(lo < hi)
    
        int mid = lo + (hi - lo)/2;

        if(a[mid] < x) lo = mid + 1;
        else           hi = mid;
    

    return hi;

所以正文只是一个标准的二分查找正文,包含mid的非溢出计算。

决定应将lohi 中的哪一个分配给mid 也很直接地遵循不变量:

如果a[mid] &lt; xa[mid] 应在a[0..lo) 范围内,因此lo = mid + 1。 反之,如果a[mid] &gt;= x,那么a[mid]属于a[hi..n),所以hi = mid

return 语句也是不言自明的,因为给定不变量为真a[hi]a 中满足a[i] &gt;= x 的最小元素。

最后要看的是while循环中的条件,具体来说,如果lo &gt;= hi,这个循环将停止,考虑到不变量,只有lo = hi才会发生。此时a[lo..hi)empty,表示搜索空间已用完。

这个实现的接口与你指定的略有不同,因为如果数组中没有这样的元素,那么它将a[hi..n)的范围视为空,当@ 987654352@。这意味着它不是返回-1,而是返回n,这很容易检查,但如果你想让它返回-1,只需将return语句替换为:

return hi < n ? hi : -1;

【讨论】:

以上是关于二进制搜索以获取第一个整数的位置> =搜索的整数的主要内容,如果未能解决你的问题,请参考以下文章

使用迭代器位置的线性和二进制搜索

使用二进制搜索检查二维数组中是否有元素存在[关闭]。

上机实践报告

上机实践报告

上机实践报告

在数组中正确放置的二进制搜索