[英]Searching for a range [x,y] in a sorted vector in C++ [using lower_bound() and upper_bound() ]
[英]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
时,永远不要陷入不改变l
或r
的循环中。 这在二进制搜索中已经足够普遍,我在代码中注释了我认为没有发生这种错误的原因。
然后,您需要精确定义l
和r
位置,以查看边界情况是否安全。 l
仅传递<value1
元素,因此我们确保不会传递第一个可能==value1
元素。 r
备份的项目不是<value1
因此可能会备份==value1
项目,因此在多个匹配value1
项目的边界情况下,我们似乎找到了第一个。 这是您可能会或可能不想更改的偶然“设计选择”。 但是否则,我们至少看到r
永远不会备份到<value1
的项目
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.