오늘은 백준을 풀다가 map 대신에 사용할만한 좋은 STL을 하나 찾아와서 소개하려고 한다. 바로 set이다.
map을 알고 보는 것이 좀 더 이해가 쉬울 것이다.
이 set은 노드 기반 트리다. 그리고 map이 key와 value 두 개의 정보를 가지고 있는, 그러니까 pair 형태로 정보를 가지는 반면, 이 set은 key 하나만을 가진다. 그리고 map처럼 똑같이 key는 중복이 안된다. 그리고 역시 map과 똑같이 insert하고 나면 자동으로 정렬이 된다(디폴트 정렬기준은 당연히 오름차순).
#include <set>
set을 include 함으로써 사용할 수 있고, 선언 방법 역시 map과 비슷하다.
set<type> s;
type은 자료형을 말하고, s는 변수 이름이다. 물론 set 역시 pair로 선언이 가능하다.
set<pair<int, string>> s;
아 참고로 이렇게 pair 형태로 set을 선언했다고 이게 map과 사실상 똑같은 거 아니냐! 이렇게 생각하면 안된다. 왜냐면 map은 pair에서 first가 key, second가 value인 반면, 저렇게 set을 pair로 선언하면 first와 second 모두 key니까..
이제 키워드들을 좀 살펴보자. 일단 똑같이 begin(), end() 존재하고, clear()도 존재한다. empty()도 존재하고, insert(i)를 통해 i라는 원소를 key로써 삽입해줄 수도 있다. 그리고 이 때 위에서 말했듯 중복되면 삽입이 안되는데, 이 삽입 성공 여부를 반환값으로 알 수 있는데, 반환값은 pair<iterator, bool>이다. iterator는 삽입한 원소를 가리키는 반복자고, bool은 삽입 성공 여부를 알려준다.
이외에도 erase(i)도 있는데, 괄호안에 iterator가 들어가면 해당 원소 제거, start와 end 두 개가 들어가면(erase(start,end)) start부터 end 전까지의 원소들을 모두 삭제한다. 중요한건 start를 포함, end는 미포함한다는 것이다. 그리고 find(i)도 존재하고, 벡터처럼 upper_bound와 lower_bound도 존재한다. 당연히 size()도 존재한다.
따로 깊게 설명하지 않는 이유는, map과 너무 유사하기도 하고, 이게 다양한 stl들을 공부해보면 알겠지만, 모두 벡터형태라서 사실 주요함수나 기능들이 모두 유사하다. 그래서 사실 벡터만 잘 공부해놔도 나머지 stl들을 공부할 때 큰 어려움이 없다.
그리고 set의 경우, map을 적절히 잘 쓸 줄 안다면, 문제없이 활용이 가능할 것이다. 내가 set을 갑자기 공부한 이유는 백준 문제를 풀 때 단순히 삽입 시 중복 여부만 확인하면 되는데 set을 몰라서 그냥 map을 써서 풀었다(당연히 value값은 필요가 없었다..). 근데 그냥 중복 여부만 확인하고 싶으면 set을 쓰면 된다. 항상 공부한 stl들은 백준에서 최대한 활용해보려고 노력하도록 하자!