[英]Binary Search for a range
I was making binary search program to find the number of elements between the Left and Right values in a range . 我正在制作二进制搜索程序,以查找范围内Left和Right值之间的元素数。
I code it : 我编码:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<int> arr(20);
int search(int value,int low,int high)
{
if (high <= low)
return low;
int mid = (low + high) / 2;
if (arr[mid] > value)
return search(value,low,mid-1);
else
return search(value,mid+1,high);
}
int main(){
int n;
cin>>n;
//ENTER SORTED ARRAY
for(int i=0;i<n;i++){
cin>>arr[i];
}
int left;
cin>>left;
//RIGHT IS GREATER OR EQUAL TO LEFT
int right;
cin>>right;
cout<<search(right,0,n-1)-search(left,0,n-1)+1<<"\n";
}
It's giving right answer for some ranges. 在某些范围内给出正确的答案。
But for some its giving wrong like If N=6 and array be [1 3 5 8 10 13] and say the range be [5,9] then it's giving 1 as the answer but it should be 2 as 5 and 8 both are in the range. 但是对于某些错误,例如如果N = 6且array为[1 3 5 8 10 13]并说范围为[5,9],则给出1作为答案,但应为2,因为5和8都是在范围中。
try this 尝试这个
int search(int value,int low,int high)
{
if (high <= low)
return low;
int mid = (low + high) / 2;
if(arr[mid]==value){ // add this line it would be work for you
return mid;
}
if (arr[mid] > value)
return search(value,low,mid-1);
else
return search(value,mid+1,high);
}
and make correction in main() 并在main()中进行更正
cout<<search(right,0,n-1)-search(left,0,n-1)<<"\n";
int search(int value,int low,int high)
{
if (high <= low + 1)
return low;
int mid = (low + high) / 2;
if (arr[mid] > value)
return search(value,low,mid);
else
return search(value,mid,high);
}
And in your main function 而在你的主要职能
cout<<search(right+1,0,n-1)-search(left,0,n-1)<<"\n";
One problem is that when arr[mid] == value
, you just ignore it and recurse to the right. 一个问题是,当
arr[mid] == value
,您只需忽略它并向右递归即可。
You'll need to either include mid
in your right range, or return mid
if arr[mid] == value
. 您需要在正确的范围内包含
mid
,如果arr[mid] == value
,则返回mid
。
I also see duplicate values (if these are possible) being a problem - when recursing to find the left-most position, you need to find the first duplicate value, when recursing to find the right-most position, you need to find the last duplicate value, so a single function without a flag to indicate which one we're doing isn't going to work. 我还看到重复值(如果可能的话)是一个问题-递归查找最左边的位置时,您需要找到第一个重复值;递归查找最右边的位置时,您需要找到最后一个值重复值,因此没有标志来指示我们正在执行的功能的单个函数将无法工作。 To illustrate the problem:
为了说明问题:
If the range is [5,5]
and the input is [1,2,5,5,5,6,8]
, the same recursive call finding the position of 5
will always return the position of the same 5
, where-as you need to return index 2
for the left range and index 4
for the right, as to get 3
as your output. 如果范围是
[5,5]
并输入为[1,2,5,5,5,6,8]
相同的递归调用查找的位置5
将总是返回相同的位置5
,如─因为您需要返回左侧范围的索引2
和右侧的索引4
,以获取3
作为输出。
There is no check that arr[mid]
can be == value. 没有检查
arr[mid]
可以==值。 In your example, first iteration for left == 5 gives mid == ( 0 + (6-1) )/2 = 5/2 = 2 and arr[2] is exactly 5. We should stop, but your code goes to the branch search(5, 3, 5);
在您的示例中,left == 5的第一次迭代得到mid ==(0 +(6-1))/ 2 = 5/2 = 2,而arr [2]恰好是5。我们应该停止,但是您的代码转到分支
search(5, 3, 5);
The logic of your program seems wrong, if you want to find the number of elements in the arr
that are in the range of [left,right], try this: 程序的逻辑似乎是错误的,如果您想在
arr
中找到[left,right]范围内的元素数量,请尝试以下操作:
int i;
int count = 0;
for(i = 0; i < n; i++) {
if (arr[i] >= left && arr[i] <= right)
count++;
}
If you insist on using binary search try this : 如果您坚持使用二进制搜索,请尝试以下操作:
static int search(int value,int low,int high)
{
if (high <= low)
return low;
int mid = (low + high) / 2;
if (arr[mid] == value)
return mid;
int idx;
if (arr[mid] > value)
idx = search(value,low,mid-1);
else
idx = search(value,mid+1,high);
if (value == arr[idx]) {
return idx;
}
else {
if(value > arr[idx])
return mid +1;
else
return mid;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.