std::set / <set>

<set>은 C++의 표준 라이브러리인 STL(Standard Template Library)의 컨테이너 중 하나다. 

주요 특징은 다음과 같다. 

  • 중복을 허용하지 않는 고유한 요소들로 구성됨
  • 요소들이 오름차순으로 자동 정렬
  • 이진 탐색 트리 중 하나인 Red-Black Tree(자가 균형 이진 탐색 트리)를 기반으로 함
  • 삽입/검색/삭제 시 탐색 속도 O(log n)을 보장함
  • 요소들이 논리적으로 연결되어 있지만 물리적으로 연결되지 않음 (연속된 메모리 블록 X)

 

1. Set 선언

+) std::greater<> 활용하여 내림차순으로 정렬 순서 변경 가능

#include <iostream>
#include <set>

int main() {
    std::set<int> s = {5, 2, 8, 1, 3};
    
    // 내림차순 정렬
    // std::set<int, std::greater<int>> s = {5, 2, 8, 1, 3}; → {8, 5, 3, 2, 1}

    for (int x : s) {
        std::cout << x << " "; // 1 2 3 5 8
    }
}

 

2. 주요 함수 및 연산

  • 삽입 / insert() : 특정 요소 추가, 중복 요소 추가 불가능
  • 삭제 / erase() : 특정 요소 삭제, 해당 요소 없으면 변화 없음
  • 탐색 / find() : 특정 요소를 가리키는 iterator를 반환, 없으면 end()에 해당하는 iterator 반환
  • 범위 삭제 / erase(a, b) : 요소 [a, b) 범위에 해당하는 모든 요소 삭제
  • 크기 확인 / size() : 총 요소의 개수 반환
#include <iostream>
#include <set>

int main() {
    std::set<int> s = {5, 2, 8, 1, 3}; // → {1, 2, 3, 5, 8}

    s.insert(4);  // 4 삽입 → {1, 2, 3, 4, 5, 8}
    s.insert(2);  // 이미 존재 → 삽입되지 않음
    
    s.erase(3);  // 값 3 삭제 → {1, 2, 4, 5, 8}
    
    if (s.find(5) != s.end()) {		// 값 5 탐색
    	std::cout << "5 exists in the set.";
    } else {
    	std::cout << "5 does not exists in the set.";
    }
    
    auto it1 = s.find(2); // 값 2의 iterator
    auto it2 = s.find(5); // 값 5의 iterator
    s.erase(it1, it2); // 값 [2, 5) 범위 삭제 (2, 4 삭제)
    
    std::cout << s.size();  // 현재 원소 개수 출력 → 3

    for (int x : s) {
        std::cout << x << " "; // 1 5 8
    }
}

 

3. 파생 라이브러리

  • <multiset> : <set>은 중복 요소를 허용하지 않지만, <multiset>은 중복을 허용함
  • <unordered_set> : <set>과 달리 정렬하지 않음, Hash table을 사용하여 탐색 속도 O(1)을 보장함
#include <iostream>
#include <set>
#include <unordered_set>

int main() {
    std::multiset<int> ms = {2, 1, 2, 3, 4, 3};		// 중복 허용
    std::unordered_set<int> us = {3, 1, 2, 4};		// 정렬 X
    
    for (int x : ms) {
        std::cout << x << " ";  // 1 2 2 3 3 4
    }
    
    for (int y : us) {
        std::cout << y << " ";  // 3 1 2 4
    }
}

 

4. 활용 예제

추가로 <random> 라이브러리를 사용한 로또 번호 무작위 추첨

#include <iostream>
#include <random>
#include <set>

void cal() {
	std::set<int> numbers;
	std::random_device rd;
	std::mt19937 gen(rd());
	std::uniform_int_distribution<int> dis(1, 45);

	while (numbers.size() < 6) {
		numbers.insert(dis(gen));
	}

	for (int num : numbers) {
		std::cout << num << " ";
	}
	std::cout << std::endl << std::endl;
}

int main() {
	int count;

	std::cout << "[로또 번호 자동 추첨기]" << std::endl << std::endl;
	std::cout << "추첨할 총 횟수를 입력하세요 : ";
	std::cin >> count;
	std::cout << std::endl;

	for (int i = 0; i < count; i++) {
		cal();
	}

	return 0;
}

 

+ Recent posts