function for finding last item less-than-or-equal to, like lower_bound

前端 未结 5 1740
南方客
南方客 2021-01-30 12:52

Is there a function in that uses binary search, like lower_bound but that returns the last item less-than-or-equal-to according to a given predic

相关标签:
5条回答
  • 2021-01-30 13:34

    Here is a wrapper function around upper_bound which returns the largest number in a container or array which is less than or equal to a given value:

    template <class ForwardIterator, class T>
      ForwardIterator largest_less_than_or_equal_to ( ForwardIterator first, 
                                                      ForwardIterator last,
                                                      const T& value)
    {
      ForwardIterator upperb = upper_bound(first, last, value);
    
      // First element is >, so none are <=
      if(upperb == first)
        return NULL;
    
      // All elements are <=, so return the largest.
      if(upperb == last)
        return --upperb;
    
      return upperb - 1;
    }
    

    For a better explanation of what this is doing and how to use this function, check out:

    C++ STL — Find last number less than or equal to a given element in an array or container

    0 讨论(0)
  • 2021-01-30 13:35

    In a sorted container, the last element that is less than or equivalent to x, is the element before the first element that is greater than x.

    Thus you can call std::upper_bound, and decrement the returned iterator once. (Before decrementing, you must of course check that it is not the begin iterator; if it is, then there are no elements that are less than or equivalent to x.)

    0 讨论(0)
  • 2021-01-30 13:40

    std::prev: https://en.cppreference.com/w/cpp/iterator/prev

    #include <iostream>
    #include <map>
    
    int main()
    {
        std::map<int, char> m{{2, 'a'}, {4, 'b'}, {6, 'c'}, {8, 'd'}, {10, 'e'}};
    
        int num = 3;
        auto it = m.upper_bound(num);
        auto pv = std::prev(it);
    
        std::cout << "upper bound of " << num << ": "
            << it->first << ", " << it->second << '\n';
        std::cout << "lower than or equal of " << num << ": "
            << pv->first << ", " << pv->second << '\n';
    }
    

    Output:

    upper bound of 3: 4, b
    lower than or equal than 3: 2, a
    
    0 讨论(0)
  • 2021-01-30 13:44

    A simple implementation in Python:

    def bi_search(arr, target):
        """
        index of the last element which <= target
        """
    
        lo, hi = 0, len(arr)
        while lo < hi:
            mid = lo + (hi - lo) // 2
            if arr[mid] <= target:
                lo = mid + 1
            else:
                hi = mid
        return lo - 1
    
    0 讨论(0)
  • 2021-01-30 13:51

    I have test your reverse iterator solution, it is correct.

    Given v is sorted by '<'

    Find last element less than x:

    auto iter = std::upper_bound(v.rbegin(), v.rend(), x, std::greater<int>());
    if(iter == v.rend())
        std::cout<<"no found";
    else
        std::cout<<*iter;
    

    Find last element less than equal x:

    auto iter = std::lower_bound(v.rbegin(), v.rend(), x, std::greater<int>());
    if(iter == v.rend())
        std::cout<<"no found";
    else
        std::cout<<*iter;
    

    This is better than iter -= 1 version

    0 讨论(0)
提交回复
热议问题