0

There is a upper_bound(), returns an iterator to the first element that is greater than val.

There is a lower_bound(), returns an iterator to the first element that is not less than val.

Is there an algorithm that returns an iterator to the first element that is not greater than val, or I have to reinvent the wheel?

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int main()
{
    std::vector<int> data = { 1, 1, 2, 3, 3, 3, 3, 5, 5, 6 };

    auto lower = std::lower_bound(data.begin(), data.end(), 4, [](int x, int y) {return x > y;});

    cout << *lower ;
}

Output: 1, expexted 3

Note that another predicate like std::greater<> doesn't work.

erip
  • 16,374
  • 11
  • 66
  • 121
vlad4378
  • 803
  • 1
  • 9
  • 21

2 Answers2

3

Just use the predicate as in your code, but traverse it in reverse order with rbegin and rend

Leandro T. C. Melo
  • 3,974
  • 22
  • 22
1

My two bits, you forgot to sort in descending order.

int main()
{
    vector<int> data = { 1, 1, 2, 3, 3, 3, 3, 5, 5, 6 };

    int wanted {4};
    sort(begin(data), end(data), greater<int>());
    auto bound =  upper_bound(begin(data), end(data), wanted, greater<int>());
    cout << "val with upper_bound: " << *bound << endl;


}

result:  val with upper_bound: 3

or one step below with partition_point:

template <typename T>
struct greater_than {
    T x;
    bool operator()(const T& y) { return y > x; }
};

int main() 
{
 ...
 auto p_point = partition_point(begin(data), end(data),
                               greater_than<int>{wanted});

 cout << "val with partition_point: " << *p_point << endl;
// val with partition_point: 3
Marko Tunjic
  • 1,811
  • 1
  • 14
  • 15