[탐색 알고리즘] lower_bound, upper_bound

Programming/알고리즘|2021. 6. 14. 15:07
반응형

안녕하세요.

playground입니다.

이번에 알아볼 내용은 탐색 알고리즘 함수 lower_bound, upper_bound에 대해 알아보겠습니다.

먼저 이 두 함수는 이진탐색 기반의 함수이고, 정렬된 리스트로 가정하고 쓸 수 있는 함수입니다.

 


- lower_bound 함수

template <class _FwdIt, class _Ty>
_FwdIt lower_bound(_FwdIt first, _FwdIt last, const _Ty& value);

 

- [범위 first, 범위 last] 중에서 value(키값)와 같거나 큰 최초의 위치를 반환

 

예를 들어 

[1, 3, 5, 7, 7] 이라는 범위를 리스트가 있고 찾으려는 키값이 7이라면

빨간색 화살표 위치인 주소값을 반환합니다.

 


 

- lower_bound 예제

 

한 번 lower_bound 함수를 써보겠습니다.

 

#include <iostream>
#include <algorithm>
using namespace std;

const int iMAX = 100000000;
int iCount, k; 
int iArr[iMAX] = {};

int main()
{
     setbuf(stdout, NULL);
     scanf("%d", &iCount);
     for (int i = 0; i < iCount; ++i)
          scanf("%d", &iArr[i]);

     scanf("%d", &k);

     // lower_bound
     int* a = lower_bound(iArr, iArr + iCount, k);

     // 아래와 같이 해야 원하는 자리값을 구할 수 있다.
     // int a = lower_bound(iArr, iArr + iCount, k) - iArr + 1;
}

 

입력

1 3 5 7 7 이 값을 넣어주고 찾으려는 값은 7라고 해보겠습니다.

 

위와 같이 lower_bound 함수에

첫번째 인자값에는 배열의 첫번째 주소,

두번째 인자값에 마지막 주소값,

세번째 인자값에 찾고 싶은 key값을 넣어줍니다.

 

 

출력

 

lower_bound 함수는 주소값을 리턴하기 때문에 a를 포인터변수로 받아서 확인해봤습니다.

위 코드를 디버깅하면 a[1 3 5 7 7]배열 중에서 iArr[3] 주소값(값 : 7)이 된 걸 확인할 수 있습니다. 

만약에 원하는 위치를 반환하게 하고 싶으면 아래와 같은 코드여야 됩니다.

 

 

int a = lower_bound(iArr, iArr + iCount, k) - iArr + 1;

 

 

해당 주소값에서 배열 첫번째 주소값을 빼면 차이값이 나오는데 보통은 첫번째를 1부터 시작하므로 1을 더해줍니다.

이러면 원하는 자리값을 구할 수 있습니다.

 


- lower_bound 직접 구현하기

int lower_bound(int _s, int _e)
{
     while (_e - _s > 0)
     {
          int m = (_s + _e) / 2;

          if (iArr[m] < k)
               _s = m + 1;
          else
               _e = m;
     }
     return _e + 1;
}

주소값을 리턴하는 함수는 아니지만 lower_bound 기능을 하는 함수입니다.

 

 

 

 


- upper_bound 함수

 

template <class _FwdIt, class _Ty>
_FwdIt upper_bound(_FwdIt first, _FwdIt last, const _Ty& value);

 

 

- [범위 first, 범위 last] 중에서 value(key값)보다 큰 수가 처음으로 등장하는 위치 찾는 함수

 

예를 들어 

[1, 3, 5, 7, 8] 이라는 범위를 리스트가 있고 찾으려는 키값이 7이라면 7 다음 수인

빨간색 화살표 위치인 주소값을 반환합니다.

 


- upper_bound  예제

 

#include <iostream>
#include <algorithm>
using namespace std;

const int iMAX = 100000000;
int iCount, k; 
int iArr[iMAX] = {};

int main()
{
     setbuf(stdout, NULL);
     scanf("%d", &iCount);
     for (int i = 0; i < iCount; ++i)
          scanf("%d", &iArr[i]);

     scanf("%d", &k);

     // upper_bound
     int* a = upper_bound(iArr, iArr + iCount, k);

     // 아래와 같이 해야 원하는 자리값을 구할 수 있다.
     // int a = upper_bound(iArr, iArr + iCount, k) - iArr + 1;
}

 

입력

1 3 5 7 8 이 값을 넣어주고 찾으려는 값은 7라고 해보겠습니다.

 

 

출력

lower_bound 함수는 주소값을 리턴하기 때문에 a를 포인터변수로 받아서 확인해봤습니다.

위 코드를 디버깅하면 a [1 3 5 7 8]배열 중에서 iArr[4] 주소값(값 : 8)이 된 걸 확인할 수 있습니다. 

 


- upper_bound 직접 구현하기

int upper_bound(int _s, int _e)
{
     while (_e - _s > 0)
     {
          int m = (_s + _e) / 2;

          if (iArr[m] <= k)
               _s = m + 1;
          else
               _e = m;
     }
     return _e + 1;
}

 

 

 

이번 포스팅에서는 lower_bound, upper_bound에 대해 알아봤습니다.

읽어주셔서 감사합니다.

 

 

 

반응형

'Programming > 알고리즘' 카테고리의 다른 글

[정렬] 버블정렬  (0) 2018.09.04
[정렬] 삽입정렬  (0) 2018.08.10
[정렬] 선택정렬  (1) 2018.08.03
[정렬] 퀵정렬  (0) 2018.06.28
[허프만] 허프만 코딩 원리와 구현  (0) 2018.04.27

댓글()