이분 탐색/upper & lower_bound

[C++] set 사용법

4gats 2024. 8. 6. 11:29

set은 "Unique한 원소"들을 "정렬에 따라"

저장하는 "컨테이너"이다.

set 안에 한 번 삽입한 데이터는 수정할 수 없다.

insert, erase를 통해 삽입 삭제만 가능하다.

 

구현 과정에서 중복이 없고

정렬이 필요한 배열이라면?

set을 사용하는 것도 나쁘지 않다.

init() 함수에서 clear() 함수를 사용하는 것도 가능하다.

lower_bound, upper_bound는 무조건 사용한다.

 

#include <set>

set<int> s;  -> 오름차순 set

set<int, greater<int>> s; -> 내림차순 set

 

set은 이터레이터로만 동작한다.

auto를 사용해서 이터레이터 변수를 지정하자.

*iter로 set 안의 원소에 접근한다.

 

<set 순회하기>

1
2
3
for(auto iter = s.begin(); iter != s.end(); iter++){
    cout << *iter << ' ';
}
cs

 

주의!!

begin()은 iter가 존재한다

end()는 마지막 원소 "다음"이다!!!

set의 마지막 원소에 접근하려면

prev(s.end());를 하거나 rbegin()을 사용한다.

1
2
3
4
5
auto iter1 = prev(league_upper[idx].end());
auto iter2 = league_lower[idx].begin();
 
if(*iter1 < *iter2)
    return;
cs

 

 

멤버 함수들

find, erase

1
2
3
4
5
6
7
8
9
inline void make_dead(int& hash, int idx) {
    auto& now = hash_map[hash];
 
    // set에서 idx 값을 가진 요소를 찾아 삭제
    auto it = now.find(idx);
    if (it != now.end()) {
        now.erase(it);
    }
}
cs

 

시간 복잡도는 O(log N)이므로 효율적이다.

 

lower_bound, upper_bound

distance 함수

1
2
auto it = dead_idx.lower_bound(ans);
int dist = distance(dead_idx.begin(), it);
cs

 

distance는 이터레이터 간의 원소가 몇 개인지 알려준다.