标准库中二分搜索算法:每个算法都提供两个版本,第一个版本用元素类型的小于运算符(<)来检测元素,第二个版本则使用给定的比较操作。给定的比较操作可以是函数对象、lambda表达式、定义函数调用操作符类的对象。
lower_bound(beg, end, val);
lower_bound(beg, end, val, comp);
返回一个迭代器,表示第一个大于等于val的元素,如果不存在这样的元素,则返回end。
upper_bound(beg, end, val);
upper_bound(beg, end, val, comp);
返回一个迭代器,表示第一个大于val的元素,如果不存在这样的元素,则返回end。
equal_range(beg, end, val);
equal_range(beg, end, val, comp);
返回一个pari对,其中first成员是lower_bound返回的迭代器,second成员是upper_bound返回的迭代器。
example:给定一个数字,求该数字在有序数组中出现的次数。
方法一:我们可以使用标准库equal_range算法,因为该算法返回一个pair对,其中first指向第一个大于等于val的位置,而second则指向第一个大于val的位置,如果数组中有多个val则second减去first就是重复元素的个数,如果数组中不存在在这样的val,则second和first指向相同的位置,两者想减为零。
int GetNumberOfK(vector<int> data, int k)
{
auto it = equal_range(data.begin(), data.end(), k);
return it.second - it.first;
}
方法二:我们可以找到首次出现val值的位置,然后从当前位置开始向后遍历,直到第一个不等于val值的位置位置,两个位置想减就是元素val出现的次数。
int GetNumberOfK(vector<int> data, int k)
{
int start = 0;
int last = data.size();
while (start < last)
{
int mid = (start + last) / 2;
if (data[mid] >= k)
last = mid;
else
start = mid + 1;
}
int sum = 0;
for (int i = last; i < data.size(); ++i)
{
if (data[i] == k)
{
sum++;
}
else
{
break;
}
}
return sum;
}