이 튜토리얼에서는 C++의 STL set 컨테이너에서 요소를 삽입하고 삭제하는 방법을 예제 코드와 함께 자세히 살펴보겠습니다.
set 컨테이너란?
set은 STL에서 제공하는 연관 컨테이너(associative container)입니다. 다음과 같은 특징을 가지고 있습니다.
- 중복 불가: 동일한 값을 가진 요소를 하나만 저장할 수 있습니다.
- 자동 정렬: 요소들이 항상 정렬된 상태로 유지되므로, 순회 시 항상 오름차순으로 값에 접근할 수 있습니다.
- 빠른 검색: 내부적으로 균형 이진 탐색 트리(레드-블랙 트리) 기반으로 구현되어 있어 삽입, 삭제, 검색이 O(log n)의 시간 복잡도를 가집니다.
삽입(Insertion) 예제
set에는 세 가지 방식으로 요소를 삽입할 수 있습니다.
- 단일 요소 삽입:
insert(value)— 삽입 성공 여부를 나타내는pair<iterator, bool>을 반환합니다. - 힌트 위치 지정 삽입:
insert(iterator, value)— 반복자가 가리키는 위치 근처에 삽입하여 성능을 최적화할 수 있습니다. - 범위 삽입:
insert(first, last)— 배열이나 다른 컨테이너의 일정 범위를 한 번에 삽입합니다.
#include<iostream>
#include<set>
using namespace std;
int main(){
set<int> st;
// 반복자 선언
set<int>::iterator it = st.begin();
set<int>::iterator it1, it2;
pair< set<int>::iterator,bool> ptr;
// 단일 요소 삽입
ptr = st.insert(20);
if (ptr.second)
cout << "새로운 요소가 삽입되었습니다";
else cout << "이미 존재하는 요소입니다";
cout << "\n첫 번째 삽입 후 set의 요소들 : ";
for (it1 = st.begin(); it1!=st.end(); ++it1)
cout << *it1 << " ";
// 힌트 위치를 지정한 삽입
st.insert(it, 24);
cout << "\n두 번째 삽입 후 set의 요소들 : ";
for (it1 = st.begin(); it1!=st.end(); ++it1)
cout << *it1 << " ";
// 배열 범위 삽입
int arr[3] = { 25, 24, 26 };
st.insert(arr, arr+3);
cout << "\n세 번째 삽입 후 set의 요소들 : ";
for (it1 = st.begin(); it1!=st.end(); ++it1)
cout << *it1 << " ";
}실행 결과
새로운 요소가 삽입되었습니다 첫 번째 삽입 후 set의 요소들 : 20 두 번째 삽입 후 set의 요소들 : 20 24 세 번째 삽입 후 set의 요소들 : 20 24 25 26
주목할 점은 배열에 중복된 값인 24가 포함되어 있지만, set의 특성상 한 번만 저장된다는 것입니다. 또한 반환된 ptr.second 값을 확인하면 해당 요소가 새로 삽입되었는지, 아니면 이미 존재했는지 판별할 수 있습니다.
삭제(Deletion) 예제
erase() 함수 역시 세 가지 방식으로 사용할 수 있습니다.
- 반복자로 삭제:
erase(iterator)— 반복자가 가리키는 요소를 삭제합니다. - 값으로 삭제:
erase(value)— 해당 값을 가진 요소를 삭제하며, 삭제된 개수를 반환합니다. - 범위 삭제:
erase(first, last)— 지정한 범위의 모든 요소를 삭제합니다.
#include<iostream>
#include<set>
using namespace std;
int main(){
set<int> st;
// 반복자 선언
set<int>::iterator it;
set<int>::iterator it1;
set<int>::iterator it2;
pair< set<int>::iterator,bool> ptr;
// set에 값 삽입
for (int i=1; i<10; i++)
st.insert(i*5);
cout << "삽입 후 set의 요소들 : ";
for (it1 = st.begin(); it1!=st.end(); ++it1)
cout << *it1 << " ";
it = st.begin();
cout << endl;
++it;
// 반복자가 가리키는 요소 삭제
st.erase(it);
cout << "첫 번째 삭제 후 set의 요소들 : ";
for (it1 = st.begin(); it1!=st.end(); ++it1)
cout << *it1 << " ";
// 값으로 삭제
st.erase(40);
cout << "\n두 번째 삭제 후 set의 요소들 : ";
for (it1 = st.begin(); it1!=st.end(); ++it1)
cout << *it1 << " ";
// 범위 삭제
++it;
++it;
++it;
++it;
st.erase(it, st.end());
cout << "\n세 번째 삭제 후 set의 요소들 : ";
for (it1 = st.begin(); it1!=st.end(); ++it1)
cout << *it1 << " ";
cout << endl;
}실행 결과
삽입 후 set의 요소들 : 5 10 15 20 25 30 35 40 45 첫 번째 삭제 후 set의 요소들 : 5 15 20 25 30 35 40 45 두 번째 삭제 후 set의 요소들 : 5 15 20 25 30 35 45 세 번째 삭제 후 set의 요소들 : 5 15 20
정리
C++ STL의 set은 중복 없는 정렬된 데이터 집합이 필요할 때 매우 유용한 컨테이너입니다. insert()와 erase() 함수는 각각 단일 요소, 힌트 위치, 범위 지정 등 다양한 형태로 오버로딩되어 있으므로, 상황에 맞게 활용하면 됩니다. 특히 값 기반 삽입 시 반환되는 pair 객체를 활용하면 중복 여부를 손쉽게 확인할 수 있다는 점을 기억해 두시기 바랍니다.