其他分享
首页 > 其他分享> > c – 上限和下限的基本二进制搜索之间的差异?

c – 上限和下限的基本二进制搜索之间的差异?

作者:互联网

在文章http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=binarySearch中,作者讨论了二进制搜索.他区分了找到某些东西是真的最低值,以及某些东西是假的最高值.
被搜索的数组看起来像:

false false false true true

我很好奇为什么这两个案例不同.为什么你不能找到真实的最低值,然后减去一个找到最高值,这是假的?

Edit2:好的,所以我理解下限和下限.现在,我在努力理解,当搜索大于或等于查询的最小整数时,为什么我们不能只将if(mid>查询)更改为if(mid> = query)并让它更低上限

编辑:这是文章所说的内容:

“现在我们终于找到实现二进制搜索的代码,如本节和前一节所述:

binary_search(lo, hi, p):
   while lo < hi:
      mid = lo + (hi-lo)/2
      if p(mid) == true:
         hi = mid
      else:
         lo = mid+1

   if p(lo) == false:
      complain                // p(x) is false for all x in S!

   return lo         // lo is the least x for which p(x) is true

如果我们想要找到p(x)为假的最后一个x,我们将设计(使用与上面类似的基本原理)类似于:

binary_search(lo, hi, p):
   while lo < hi:
      mid = lo + (hi-lo+1)/2    // note: division truncates
      if p(mid) == true:
         hi = mid-1
      else:
         lo = mid

   if p(lo) == true:
      complain                // p(x) is true for all x in S!

   return lo         // lo is the greatest x for which p(x) is false

“.

解决方法:

二进制搜索的下限和上限是可以插入值的最低和最高位置,而不会破坏排序. (在C标准库中,这些边界将由引用可在其中插入值的元素的迭代器表示,但概念基本上没有更改.)

例如,排序范围

1 2 3 4 5 5 5 6 7 9

在二进制搜索3中,我们将拥有

   v-- lower bound
1 2 3 4 5 5 5 6 7 9
     ^-- upper bound

并在二进制搜索5:

       v-- lower bound
1 2 3 4 5 5 5 6 7 9
             ^-- upper bound

如果元素不在该范围内,则下限和上限相同.在二进制搜索8:

                 v-- lower bound
1 2 3 4 5 5 5 6 7 9
                 ^-- upper bound

您所引用的文章的作者用“小于”和“大于”的等效术语来表达所有这些,以便在搜索5时,

       v-- lower bound
t t t t f f f f f f      <-- smaller than?
1 2 3 4 5 5 5 6 7 9
f f f f f f f t t t      <-- greater than?
             ^-- upper bound

在所有这些情况下,C迭代器将引用绑定后面的元素.也就是说:

>在搜索3时,std :: lower_bound返回的迭代器将引用3,而std :: upper_bound中引用的迭代器将引用4
>在搜索5时,std :: lower_bound返回的迭代器将引用前5个,而std :: upper_bound引用的迭代器将引用6
>在搜索8时,两者都指9

这是因为插入的C标准库中的约定是传递一个迭代器,该迭代器引用应该插入新元素的元素.例如,之后

std::vector<int> vec { 1, 3, 4, 5, 5, 5, 6, 7, 9 };
vec.insert(vec.begin() + 1, 2);

vec将包含1,2,3,4,5,5,5,6,7,9.std :: lower_bound和std :: upper_bound遵循此约定,以便

vec.insert(std::lower_bound(vec.begin(), vec.end(), 5), 5);
vec.insert(std::upper_bound(vec.begin(), vec.end(), 8), 8);

按照需要工作,并将vec排序.

更一般地,这是在C标准库中指定范围的方式的表达.范围的起始迭代器引用范围的第一个元素(如果有),而结束迭代器引用范围末尾后面的元素(如果有).查看它的另一种方法是由std :: lower_bound和std :: upper_bound返回的迭代器跨越搜索范围中与搜索元素等效的元素范围.

如果元素不在范围内,则此范围为空,以便lower_bound和upper_bound返回相同的迭代器,否则lower_bound返回迭代器,引用搜索范围中与搜索值等效的第一个元素,而upper_bound返回迭代器引用到最后一个元素后面的元素(如果有的话).

标签:c,binary-search,lower-bound,upperbound
来源: https://codeday.me/bug/20191003/1851067.html