셋 (std::set)

셋(set)은 연관 컨테이너(Associative Container) 중 하나이다.

set 은 노드 기반으로 이루어져 있고 균형 이진 탐색 트리 구조이다.

setkey로 이루어져 있으며 key 값은 고유한 값으로 중복이 허용되지 않는다.

set 은 원소가 삽입되면서 자동으로 오름차순(기본값) 으로 정렬된다.

set 은 저장 공간의 필요에 따라 동적할당을 한다.

image.png


set 의 사용

#include <set>
std::set<KeyType> SetName;
std::set<int> s; 비어있는 셋 s를 생성
std::set<int> s2(s1); 셋 s2는 셋 s1을 복사하여 생성
std::set<int, predicate> s; predicate를 통해 정렬 기준을 세운 셋 s를 생성
std::set<int, std::greater<int>> s; // 내림차순으로 정렬하는 셋 s를 생성

set 의 멤버 함수

std::set<int> s;

s.begin() 첫 번째 원소를 가리키는 iterator 를 반환
s.end() 마지막 원소의 다음을 가리키는 iterator 를 반환
s.rbegin() 마지막 원소를 가리키는 reverse_iterator 를 반환
s.rend() 첫 번째 원소의 앞을 가리키는 reverse_iterator 를 반환
s.insert(k) 원소 k를 삽입함. 삽입 시 자동으로 정렬되며 삽입 성공/실패 여부 pair<iterator, bool>
를 반환
s.insert(iter, k) iter가 가리키는 위치부터 원소 k를 삽입할 위치를 탐색해 삽입
s.erase(k) k 값과 key 값이 일치하는 원소를 제거
s.erase(iter) iter 가 가리키는 원소를 제거
s.erase(start, end) start 반복자부터 end 반복자 전까지 [start, end) 원소를 제거
s.clear() 셋의 모든 원소를 제거
s.find(k) k 값과 key 값이 일치하는 원소를 가리키는 반복자를 반환.
만족하는 원소가 없다면 s.end() 와 같은 반복자를 반환
s.count(k) k 값과 key 값이 일치하는 원소의 개수를 반환
s.empty() 셋 s가 비어있으면 true를 반환
s.size() 원소의 개수를 반환
s.contains(k) 셋에 k 값과 일치하는 key 값이 있으면 true 를 반환 (C++20)
s2.swap(s1) s1 셋과 s2 셋을 서로 바꿈

set 의 원소 삽입

insert() 를 통해 set 에 원소를 삽입할 수 있다.

#include <iostream>
#include <set>

int main()
{
	std::set<int> s;
	std::set<int>::iterator it;

	// insert() 이용
	s.insert(50);
	s.insert(42);
	s.insert(52);
	s.insert(72);
	s.insert(57);
	s.insert(20);
	s.insert(47);

	for (it = s.begin(); it != s.end(); ++it)
		std::cout << (*it) << " ";

	// (추가) insert는 원소 삽입 성공 여부를 반환합니다.
	std::pair<std::set<int>::iterator, bool> isInsert;

	std::cout << std::boolalpha;
	isInsert = s.insert(80); // 새로운 key 값이므로 삽입 됨
	std::cout << "\\n원소 삽입 : " << isInsert.second;
	isInsert = s.insert(42); // 이미 있는 key 값이므로 삽입 되지 않음
	std::cout << "\\n원소 삽입 : " << isInsert.second;

	std::cout << std::endl;
	for (it = s.begin(); it != s.end(); ++it)
		std::cout << (*it) << " ";

	return 0;
}
20 42 47 50 52 57 72
원소 삽입 : true
원소 삽입 : false
20 42 47 50 52 57 72 80

set 의 원소 삭제

erase(), clear() 를 통해 set 의 원소를 삭제할 수 있다.

#include <iostream>
#include <set>

int main()
{
	std::set<int> s;
	std::set<int>::iterator it;

	s.insert(50);
	s.insert(42);
	s.insert(52);
	s.insert(72);
	s.insert(57);
	s.insert(20);
	s.insert(47);

	for (it = s.begin(); it != s.end(); ++it)
		std::cout << (*it) << " ";

	// key 값을 기준으로 요소 삭제
	s.erase(72);

	// iterator 를 이용해 요소 삭제
	s.erase(s.begin());

	std::cout << std::endl;
	for (it = s.begin(); it != s.end(); ++it)
		std::cout << (*it) << " ";

	// clear()를 이용해 전체 원소 삭제
	s.clear();

	if (s.empty())
		std::cout << "\\nset이 비었습니다.";
	else
		std::cout << "\\nset이 비어있지 않습니다.";

	return 0;
}
20 42 47 50 52 57 72
42 47 50 52 57
set이 비었습니다.

set 의 원소 찾기

find() 를 통해 원하는 원소를찾을 수 있다.

#include <iostream>
#include <set>

int main()
{
	std::set<int> s;
	std::set<int>::iterator it;

	s.insert(50);
	s.insert(42);
	s.insert(52);
	s.insert(72);
	s.insert(57);
	s.insert(20);
	s.insert(47);

	for (it = s.begin(); it != s.end(); ++it)
		std::cout << (*it) << " ";

	// find() 를 이용해 원하는 원소를 찾을 수 있습니다.
	it = s.find(52);
	std::cout << "\\n\\n" << (*it);

	// 만약 일치하는 key 값이 없다면 end()를 가리키는 반복자를 반환합니다.
	it = s.find(40);
	if (it != s.end())
		std::cout << "\\n\\n원소 발견!" << std::endl;
	else
		std::cout << "\\n\\n원소 미발견..." << std::endl;

	return 0;
}
20 42 47 50 52 57 72

52

원소 미발견...