lower_bound()與upper_bound()

所在頭文件:#include<algorithm>

函數分類:Binary search (operating on partitioned/sorted ranges)

函數功能:lower_bound()返回一個迭代器指針,指向val出現在這個被查找序列中出現的第一個位置;upper_bound()返回一個迭代器指針,指向val出現在這個被查找序列中出現的最後一個位置的後一個位置。

lower_bound()的函數模板功能相當於:

template <class ForwardIterator, class T>
ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last, const T& val)
{
  ForwardIterator it;
  iterator_traits<ForwardIterator>::difference_type count, step;
  count = distance(first,last);
  while (count>0)
  {
    it = first; step=count/2; advance (it,step);
    if (*it<val) 
    {                 // or: if (comp(*it,val)), for version (2)
      first=++it;
      count-=step+1;
    }
    else count=step;
  }
  return first;
}

upper_bound()的函數模板功能相當於:

ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last, const T& val)
{
  ForwardIterator it;
  iterator_traits<ForwardIterator>::difference_type count, step;
  count = std::distance(first,last);
  while (count>0)
  {
    it = first; step=count/2; std::advance (it,step);
    if (!(val<*it))                 // or: if (!comp(val,*it)), for version (2)
    { 
        first=++it; count-=step+1;  
    }
    else count=step;
  }
  return first;
}

lower()返回的是有序數組中第一次出現val的位置,如果找不到,則返回數組的最後一個位置。

upper()返回的是有序數組中最後一次出現val的位置的後一個位置,如果找不到,則返回數組的最後一個位置,如果val與數組最後一個元素相等,則返回數組的最後一個位置。

upper()除了比lower()多了一個 = 以外,其它的地方完全相同。

代碼中,array爲要查找的數組,b爲數組的起始位置,e爲數組的結束位置,val爲要查找的值,first爲指向數組中某個位置的指針,初始化爲第一個元素,count爲first指針最多能移動的位數,setp爲指針需要的位數。

lower()中,當array[it]比val小時,就一直移動first指針,且只向後移動一位(就是這裏保證了返回val第一次出現的位置;如果是array[it]等於val,則first指針不會移動,count的值會一直減少,每次減少一半,最終等於0,循環結束然後返回first;如果是array[it]大於val,則first不會移動,count會一直縮減到使得array[it]小於等於val的大小),移動後,更新最多可移動的的位數,這個值爲e與first的差,既first的右邊部分。
在數組a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}中查找 7
調用lower(a, 0, 9, 7);
first = 0; count = 9;
第一次循環:
it = 0; step = 4; it = 4; a[it] = 5; first = 5; count = 4;

第二次循環:
it = 5; step = 2; it = 7; a[it] = 8; first = 6; count = 1;

第三次循環:
it = 6; step = 0; it = 6; a[it] = 7; count = 0;

找到結束。

#include <bits/stdc++.h>
using namespace std;
int lower(int *array, int b, int e, int val)//二分查找下界
{
    int first = b;
    int count = e - b;
    while (count > 0)
    {
        int it = first;
        int step = count / 2;
        it = it + step;
        if (array[it] < val)
        {
            first = ++it;
            count = count - (step + 1);
        }
        else
        {
            count = step;
        }
    }
    return first;
}

int upper(int *array, int b, int e, int val)//二分查找上界
{
    int first = b;
    int count = e - b;
    while (count > 0)
    {
        int it = first;
        int step = count / 2;
        it = it + step;
        if (array[it] <= val)
        {
            first = ++it;
            count = count - (step + 1);
        }
        else
        {
            count = step;
        }
    }
    return first;
}

int main()
{
    int array[] = {0,1,2,3,4,5,5,5,5,5,6,6,6,7,8,9,10,11,11,11,12,12,13,13};
    int e = sizeof(array) / sizeof(int);
    int ans1 = lower(array, 0, e - 1, 11);
    int ans2 = upper(array, 0, e - 1, 11);
    printf("數組中第一次出現11的位置:              %d\n", ans1);
    printf("數組中最後一次出現11的位置的後一個位置:  %d\n", ans2);
    printf("------------------------------------------\n");
    int ans3 = lower(array, 0, e - 1, 13);
    int ans4 = upper(array, 0, e - 1, 13);
    printf("數組中第一次出現13的位置:              %d\n", ans3);
    printf("數組中最後一次出現13的位置的後一個位置:  %d\n", ans4);//此處返回數組的最後一個位置
    printf("------------------------------------------\n");
    int ans5 = lower(array, 0, e - 1, 100);
    int ans6 = upper(array, 0, e - 1, 100);
    printf("找不到 %d,返回數組的最後一個位置\n", ans5);
    printf("找不到 %d,返回數組的最後一個位置\n", ans6);
    printf("-------------\n");
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章