繁体   English   中英

使用二进制搜索来搜索向量的上限

[英]Searching vector's upper bound using binary search

给定输入(值1),我需要在向量(“ vec”)中找到其上限。 除了返回上限值外,我还需要返回指向该上限值的指针。

vector<int> vec;
vec.push_back(5); vec.push_back(7); vec.push_back(15); 

如果我的输入值为value1 =“ 13”,那么我的函数upperBound()应该返回指向元素15的指针。

upperBound()函数返回“ pointerUpperBound”-这是指向value1上限的指针。

在我的情况下,上限是指大于或等于输入值(value1)的值。 它是大于输入的最小数字

 //**GOAL OF ALGORITHM: Given "value1" it needs to find value1's upper bound  in vector "vec". Instead of return the upper bound element, I need to return pointer to upper bound element**
bool upperBound(int* &pointerUpperBound,int value1, vector<int> vec)
    // Perform a binary search
{
   unsigned left=0,right=(vec.size()-1);
   int* l=&vec[0];
   int* r=(l+vec.size()-1); //l will be start of pageInfo vector and r will be end of page info vector
   if(vec.size()==1) //vec has just one element in it.
   {
       pointerUpperBound=l;
       return true;

   }   
   while (left!=right) {
      int* pointerUpperBound=l+((r-l)/2); 
      unsigned middle=left+((right-left)/2);
      if(value> (*pointerUpperBound)) {     
         l=pointerUpperBound+1;
         left=middle+1;
      } else if (!middle) { //reached the upper bound, it is "pointerUpperBound" which is also returned.
         break;
      } else {
         int* prev=pointerToUpperBound;
         prev--;
         if(value1 > (*prev)) {
             break;
         } else{
             right=middle;
             r=pointerToUpperBound;
         }
      }
   }
   // Unsuccessful search?
   if (left==right) {
       return false;
   }
}

我的算法没有返回正确的上限。 有人可以帮我弄清楚我要去哪里错了。

我只想使用“指针”遍历此向量。 我不想使用内置函数来查找上限-因为我想了解算法出了什么问题。

看起来您正在尝试将pointerUpperBound用作输出参数,但是您通过value传递了它。

调用者将看不到您对指针所做的修改。

通过参考。

您没有考虑过请求值大于向量中任何值的情况,并且通过忽略该情况,您也弄错了其他情况。

您尚未发布测试过的真实代码,原因是:

  int* pointerUpperBound=l+((r-l)/2); 
  unsigned middle=left+((right-left)/2);
  if(value> (*pointerUpperBound)) {     
     l=m+1;

什么是m ??

所有这些多余的工作(指针和无符号副本并行)只是造成混乱的原因。 使用一个或另一个。

考虑一下您的代码(在进行上述更正之后):

  if(value> (*pointerUpperBound)) {     
     l=pointerUpperBound+1;
     left=middle+1;
  }

如果value > *r则上面的代码可以达到l=r+1; 那是您打算的那种情况吗? 如果没有,您打算做什么?

您认为决赛涉及什么情况?

   // Unsuccessful search?
   if (left==right) {
       return false;
   }

考虑一下r==l+2且您想要的答案是r 您尝试位置l+1 ,但位置太小,因此将l=l+1+1;设置l=l+1+1; 永远不要尝试该位置,因为它是r但是您只需结束循环并返回false 您从胜利的jaw口夺走了失败。


bool upperBound(int* &pointerUpperBound,int value1, vector<int> vec)
    // Perform a binary search
{
   int* l=&vec[0];  // Pointer to lowest that might be == value1
   int* r=l+vec.size(); //Pointer PAST last value that might be < value1

   while ( l < r ) {
      int* m=l+((r-l)/2); // Notice m<r, m>=l
      if( value1 > *m ) {     
         l=m+1;  // l always increases here
      } else {
         r=m;  // m always decreases here
      }
   }
   pointerUpperBound = l;  // first position >= value1
}

该代码确实很简单。 边界案例值得思考,但我认为它们都可以解决。 如果向量中的每个项目<value1,则此代码将返回向量结束之后的第一个位置。 那是一种设计选择(不是对还是错)。 如果您不喜欢这种选择,则应该易于更改。

在任何二进制搜索中,都需要注意它始终会收敛,当r==l+1时,永远不要陷入不改变lr的循环中。 这在二进制搜索中已经足够普遍,我在代码中注释了我认为没有发生这种错误的原因。

然后,您需要精确定义lr位置,以查看边界情况是否安全。 l仅传递<value1元素,因此我们确保不会传递第一个可能==value1元素。 r备份的项目不是<value1因此可能会备份==value1项目,因此在多个匹配value1项目的边界情况下,我们似乎找到了第一个。 这是您可能会或可能不想更改的偶然“设计选择”。 但是否则,我们至少看到r永远不会备份到<value1的项目

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM