C++ STL(표준 템플릿 라이브러리)에는 다양한 연관 컨테이너가 있으며, 그중 가장 널리 사용되는 것이 Set과 Map입니다. 두 컨테이너 모두 요소를 자동으로 정렬하고 키의 중복을 허용하지 않는다는 공통점이 있지만, 저장하는 데이터의 형태에서 뚜렷한 차이를 보입니다.
Set(셋)이란?
Set은 각 요소가 반드시 고유해야 하는 추상 데이터 타입입니다. 요소의 값 자체가 곧 식별자 역할을 하며, 한 번 set에 추가된 요소의 값은 직접 수정할 수 없습니다. 값을 변경하려면 해당 요소를 삭제한 후 수정된 값을 다시 삽입해야 합니다.
Map(맵)이란?
Map은 요소를 키(key)와 값(value)의 쌍으로 매핑하여 저장하는 연관 컨테이너입니다. 각 요소는 하나의 키 값과 하나의 매핑된 값을 가지며, 서로 다른 두 요소가 동일한 키 값을 가질 수 없습니다. 즉, 키는 유일해야 하지만 값은 중복될 수 있습니다.
Set과 Map의 핵심 차이점
위의 정의에서 알 수 있듯이 set은 키만 저장하고, map은 키와 값을 함께 저장합니다. 두 컨테이너 모두 키는 고유해야 하며, 내부적으로 정렬된 상태를 유지합니다.
만약 정렬이 필요 없다면 unordered_set, unordered_map을, 중복을 허용해야 한다면 multiset, multimap을 사용하면 됩니다.
| 구분 | Set | Map |
|---|---|---|
| 저장 형태 | 고유한 키만 저장 | 키와 값의 쌍(pair) 저장 |
| 중복 허용 | 허용하지 않음 | 키는 불가, 값은 가능 |
| 정렬 | 키 기준 오름차순 자동 정렬 | 키 기준 오름차순 자동 정렬 |
| 내부 구조 | 레드-블랙 트리 | 레드-블랙 트리 |
| 요소 수정 | 불가 (삭제 후 재삽입 필요) | 값만 수정 가능, 키는 불가 |
| 주요 용도 | 중복 제거, 존재 여부 확인 | 키 기반 조회, 카운팅 |
Set 예제 코드
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
int main() {
set<int> s; // 빈 set 컨테이너 초기화
set<int>::iterator it; // set 컨테이너를 반복자로 선언
s.insert(7); // set 컨테이너 s에 요소 삽입
s.insert(6);
s.insert(1);
s.insert(4);
s.insert(2);
s.insert(9);
s.insert(10);
cout << "set에 저장된 요소:\n";
for (auto it : s)
cout << it << " "; // set 컨테이너의 요소 출력
return 0;
}
실행 결과
set에 저장된 요소: 1 2 4 6 7 9 10
Map 예제 코드
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
int main()
{
map<char, int> m; // map 초기화
map<char, int>::iterator iter; // map 반복자 선언
m.insert(pair<char, int>('a', 10)); // map에 값 삽입
m.insert(pair<char, int>('b', 20));
cout << "map에 저장된 요소:\n";
for (iter = m.begin(); iter != m.end(); iter++)
cout << "[ " << iter->first << ", " << iter->second << "]\n"; // map의 값 출력
return 0;
}
실행 결과
map에 저장된 요소: [ a, 10] [ b, 20]
마무리
값의 존재 여부 확인이나 중복 제거가 목적이라면 set을, 키를 통해 특정 값을 빠르게 조회해야 한다면 map을 선택하는 것이 적절합니다. 두 컨테이너의 특성을 정확히 이해하면 더 효율적이고 깔끔한 C++ 코드를 작성할 수 있습니다.