개요
C++에서는 세트 자료구조를 갖는 컨테이너로 표준 라이브러리의 set를 사용할 수 있습니다.
set<int> s { 1, 2, 3, 4, 5 };
set는 중복되지 않는 데이터의 집합을 정렬 및 관리하는 특징을 가지며, 중복이 가능한 set로 std::multiset, 정렬하지 않는 set로 std::unordered_set를 사용할 수 있습니다.
특징
- 동적 컨테이너 크기
- 요소를 추가하거나 삭제할 때 컨테이너의 크기가 자동으로 조절됩니다.
- 중복 데이터 삽입 불가
- set에는 고유한 데이터만 저장할 수 있습니다. 이미 해당 데이터가 존재하는 경우, 삽입되지 않습니다.
- 자동 정렬
- _Pr 템플릿 매개변수를 이용하여 정렬 방식을 선택할 수 있습니다.
- 기본적으로는 less(오름차순) 정렬 객체를 사용하고, greator(내림차순) 정렬 객체를 사용하거나 사용자가 직접 작성할 수도 있습니다.
- 임의 접근 제한
- 인덱스를 이용한 특정 요소 접근이 어렵고, 임의 접근 보다는 순차적인 접근을 권장합니다.
- set는 iterator를 지원하므로 특정 인덱스의 요소에 접근하려면 iterator를 사용해야 합니다.
- set의 iterator는 ++, -- 연산만을 지원합니다.
- Red-Black Tree 구조
- 내부적으로 Red-Black Tree 구조를 사용하여 요소의 삽입 및 삭제 후 정렬까지 O(log n)의 시간복잡도를 가집니다.
헤더
#include <set>
set를 사용하기 위해서 <set> 헤더를 포함해야 합니다.
선언 및 초기화
템플릿 매개변수
set<_Kty, _Pr = less<_Kty>, _Alloc = allocator<_Kty>>
set는 타입을 선언할 때, 최대 3개의 템플릿 매개변수를 받습니다.
- _Kty은 실제 저장되는 데이터의 형식을 나타냅니다.
- _Pr은 데이터를 정렬할 비교 함수 객체를 나타냅니다. 지정하지 않으면 기본적으로 std::less 객체를 사용합니다.
- _Alloc은 할당자(Allocator)를 나타냅니다. 지정하지 않으면 기본 할당자가 사용됩니다.
생성자
set<int> s { 1, 2, 3, 4, 5 }; // 컨테이너는 { 1, 2, 3, 4, 5 }로 초기화됩니다.
set를 선언과 동시에 초기화하기 위해서 중괄호를 이용해 컨테이너의 초기 요소들을 설정할 수 있습니다.
iterator 복사
set<_Kty> s(_First, _Last);
다른 컨테이너의 iterator를 이용하여 요소를 복사합니다.
- _First는 복사할 컨테이너의 첫 iterator를 나타냅니다.
- _Last는 복사할 컨테이너의 마지막 iterator를 나타냅니다.
set 복사
set<_Kty> s(_Right);
다른 set를 복사하여 새로운 set를 생성합니다.
- _Right는 복사할 set를 나타냅니다.
주요 함수
size()
set<int> s { 1, 2, 3, 4, 5, 6 };
size_t size = s.size(); // 6을 반환합니다.
set의 크기를 반환합니다.
empty()
set<int> s { 1, 2, 3, 4, 5, 6 };
bool is_empty = s.empty(); // false를 반환합니다.
set가 비어있는지 여부(크기가 0이면 true, 그렇지 않으면 false)를 반환합니다.
count(value)
set<int> s { 1, 2, 3, 4, 5, 6 };
size_t c = s.count(6); // 1을 반환합니다.
set에 특정 값의 존재 여부(존재하면 1을, 그렇지 않으면 0)를 반환합니다.
lower_bound(value)
set<int> s { 1, 2, 3, 4, 5, 6 };
auto it = s.lower_bound(3); // 요소 '3'에 대한 iterator를 반환합니다.
set에서 특정 값(value)의 이상이 되는 가장 첫 번째 요소의 iterator를 반환합니다.
- value는 기준이 되는 값을 나타냅니다.
upper_bound(value)
set<int> s { 1, 2, 3, 4, 5, 6 };
auto it = s.upper_bound(3); // 요소 '4'에 대한 iterator를 반환합니다.
set에서 특정 값(value)의 초과가 되는 가장 첫 번째 요소의 iterator를 반환합니다.
- value는 기준이 되는 값을 나타냅니다.
find(value)
set<int> s { 1, 2, 3, 4, 5, 6 };
auto it = s.find(3); // 요소 '3'에 대한 iterator를 반환합니다.
set에서 특정 값을 갖는 요소의 iterator를 반환합니다.
- value는 찾을 값을 나타냅니다.
begin()
set<int> s { 1, 2, 3, 4, 5, 6 };
auto it = s.begin();
set에서 첫 번째 요소의 iterator를 반환합니다.
end()
set<int> s { 1, 2, 3, 4, 5, 6 };
auto it = s.end();
set에서 마지막 요소의 iterator를 반환합니다.
insert(value)
set<int> s { 1, 2, 4, 5, 6 };
s.insert(3); // 컨테이너는 { 1, 2, 3, 4, 5, 6 } 상태입니다.
set에 값을 삽입합니다.
이미 해당 값이 존재하는 경우 삽입하지 않으며, 삽입 후에는 정렬 조건에 따라 자동으로 정렬됩니다.
- value는 삽입할 값을 나타냅니다.
erase(value)
set<int> s { 1, 2, 3, 4, 5, 6 };
s.erase(3); // 컨테이너는 { 1, 2, 4, 5, 6 } 상태입니다.
set의 특정 요소의 값을 삭제합니다.
- value는 삭제할 값을 나타냅니다.
erase(first, last)
set<int> s { 1, 2, 3, 4, 5, 6 };
s.erase(s.begin(), s.end()); // 컨테이너는 { } 상태입니다.
set의 특정 요소 범위의 값을 삭제합니다.
- first는 삭제할 범위의 첫 iterator를 나타냅니다.
- last는 삭제할 범위의 마지막 iterator를 나타냅니다.
clear()
set<int> s { 1, 2, 4, 5, 6 };
s.clear(); // 컨테이너는 { } 상태입니다.
set의 모든 요소를 삭제합니다.
swap(set)
set<int> s1 { 1, 2, 3, 4, 5, 6 };
set<int> s2 { 11, 22, 33, 44, 55, 66 };
s1.swap(s2);
// s1 컨테이너는 { 11, 22, 33, 44, 55, 66 } 상태입니다.
// s2 컨테이너는 { 1, 2, 3, 4, 5, 6 } 상태입니다.
set의 모든 요소를 교환합니다.