c++ set 라이브러리에 정의되어 있는 자료구조인 set, multiset에 대해서 정리해보자. 먼저 set은 노드기반 이진 탐색 트리 구조로 삽입, 삭제, 탐색 모두 O(logN)의 복잡도를 가진다. 요소가 고유하고 자동으로 정렬되어야 할 때 유용하게 사용된다. multiset은 중복을 허용하는 set이다.
set은 일반적인 vector와 조금 다르게 사용한다. 반드시 이터레이터를 통해서 탐색해야 한다는 조건을 가진다. 앞서 말했듯이 노드기반 이진 탐색 트리 구조이고 중위순회를 하면 항상 정렬된 값을 찾을 수 있다. set은 이터레이터를 통해서 탐색하면 알아서 중위순회를 해준다. 즉 주소값에 직접적으로 연산을 하거나 myset[3]<- 이런 방식으로 탐색하지 않고 이터레이터를 통해서 순회해야한다.
#include <iostream>
#include <set>
using namespace std;
int main() {
set<int> myset;
myset.insert(1);
myset.insert(3);
myset.insert(2);
for (auto it = myset.begin(); it != myset.end(); it++)
cout << *it << ' ';
for(auto it:myset)// 이렇게도 사용이 가능하다.
cout << it << ' ';
return 0;
}
set<int> mySet;
mySet.insert(10);
mySet.insert(5);
mySet.erase(10);
auto it = mySet.find(5);
if (it != mySet.end()) {
cout << "Element found: " << *it << endl;
}
int count = mySet.count(5); // count는 1 또는 0
cout << "Set size: " << mySet.size() << endl;
mySet.clear();
for(auto it = mySet.begin(); it != mySet.end(); ++it) {
cout << *it << " ";
}
if (mySet.empty()) {
cout << "Set is empty" << std::endl;
}
auto itLow = mySet.lower_bound(5);
auto itUp = mySet.upper_bound(5);
mySet.emplace(20);
이러한 함수들을 사용하면 set 자료구조에서 요소를 삽입, 삭제, 검색, 순회할 수 있다.
멀티셋은 셋과 거의 동일하고 중복을 허용한다는 차이점만 있기 때문에 후술하진 않고 특별한 경우 한가지만 보자. 멀티셋에서 erase함수를 사용할 때, s.erase(1) 이런 식으로 값을 넣으면 모든 1값이 삭제된다. 하지만 s.erase(s.find(1))이런 식으로 반복자를 사용해서 삭제하면 하나의 값만 삭제할 수 있다.
#include <iostream>
#include <set>
using namespace std;
int main() {
multiset<int> s;
s.insert(1);
s.insert(1);
s.insert(2);
s.insert(2);
s.insert(3);
s.insert(4);
for (auto it : s)
cout << it << ' ';
cout << '\n';
s.erase(1);
s.erase(s.find(2));
for (auto it : s)
cout << it << ' ';
return 0;
}
