Reputation: 1103
Is there way to do the following search using a faster way? The items on A array are sorted in DESC order.
int find_pos(int A[], int value, int items_no, bool only_exact_match)
{
for(int i = 0; i < items_no; i++)
if(value == A[i] || (value > A[i] && !only_exact_match))
return i;
return -1;
}
Upvotes: 0
Views: 72
Reputation: 1085
You can use std::lower_bound
algorithm in your case. It performs binary search with O(log N), as other people wrote. It will be something like this:
int find_pos(int A[], int value, int items_no, bool only_exact_match)
{
const int *pos_ptr = std::lower_bound(A, A + items_no, value, std::greater<int>());
const ptrdiff_t pos = pos_ptr - A;
if (pos >= items_no)
return -1;
if (*pos_ptr != value && only_exact_match)
return -1;
return pos;
}
Upvotes: 5
Reputation: 109557
A binary search
int left = 0;
int right = items_no; // Exclusive
while (left < right) {
int mid = (left + right) / 2;
if (value == A[mid])
return mid;
if (value < A[mid]) {
left = mid + 1;
} else {
right = mid;
}
}
return only_exact_match ? -1 : right - 1; // The greater
Upvotes: 1
Reputation: 792
Because your array is sorted, you can search in steps, akin to a bisection. First, check the midpoint against your value. If it's equal, you have your answer. If it's greater, your value is in the lower half of the array. If not, your value is on the upper half. Repeat this process by bisecting the remaining elements of the array until you find your value, or run out of elements. As for your second if clause, if no matching value is found, the closest smaller element is element i+1, if that exists (i.e. you are not at the end of the array).
Upvotes: 1